我正在测试JPA2.1和新的“架构生成”功能。为此,我测试了HyperSQL数据库下的两个实现:
我对实现没有任何偏好(甚至没有性能)。我测试了EclipseLink,因为它是第一个可用的JPA2.1实现,但是现在,Hibernate 4.3在这里并且符合JPA2.1。我唯一想要的是从JPA提供程序中获取独立的东西 - 除了配置(如缓存,日志记录,静态编织......)。
至于模式生成,有几个方面让我感兴趣:
ImprovedNamingStrategy
来改进命名策略。遗憾的是,它没有使用明确的名称命名外键:FK_8gc2pk9u5bsbhpi91x93c77o
不明确,而fk_foobar_sample
是。因此,我添加了@Table
,@JoinColumn
和@Column
注释来强制我的命名策略,现在我被外键生成阻止,其支持似乎很差(当遵守JPA2.1时):
@org.hibernate.annotations.ForeignKey
,为此我需要注释字段或属性。但它是一个hibernate注释,因此它不符合JPA2.1。@JoinColumn
和foreignKey
与@ForeignKey(name="...")
放在一起,否则EclipseLink永远不会生成外键约束。但是当它生成一个外键时,缺少定义(即:ALTER TABLE foobar ADD CONSTRAINT fk_foobar_zorg FOREIGN KEY () REFERENCES ()
),而它应该根据Javadoc存在。@ManyToOne
是Hibernate生成外键(抛出异常)所必需的,而不是EclipseLink。我不明白为什么需要它:如果引用的类型带有注释@Entity
那么为什么我应该放@OneToOne
,@ManyToOne
,@OneToMany
和@ManyToMany
它可以完美地从引用的类中推断出来。@JoinColumn
的{{1}}注释的字段,EclipseLink不会生成外键约束。如何以纯粹的JPA2.1方式完成工作?
因为我的示例案例太大而无法放在Stackoverflow上,你会发现an archive有4个maven 3项目:
foreignKey
和@Table
注释的EclipseLink 2.5.2-M1。@JoinColumn
和@Table
注释的EclipseLink 2.5.2-M1和默认命名策略@JoinColumn
和@Table
注释的Hibernate 4.3和默认命名策略只需在根项目上运行@JoinColumn
,然后运行您喜欢的任何差异工具:
mvn test
也可以使用Maven Plugin for Eclipse将POM导入Eclipse(在Kepler上测试)。
作为参考,这里是不同SQL文件的结果(drop文件也是错误的,但只是因为约束名称没有重载)。
的EclipseLink
如您所见,外键约束在语法上无效; colordiff ./jpa2.1-eclipselink/database-create.sql ./jpa2.1-hibernate/database-create.sql
vimdiff ./jpa2.1-eclipselink/database-create.sql ./jpa2.1-hibernate/database-create.sql
diff ./jpa2.1-eclipselink/database-create.sql ./jpa2.1-hibernate/database-create.sql
kdiff3 ./jpa2.1-eclipselink/database-create.sql ./jpa2.1-hibernate/database-create.sql
上有两个缺失约束(一个到foobar
,另一个到zorg
。
grumph
EclipseLink(没有@Table,@ JoinColumn)
这里不足为奇:如果无法生成至少正确的内容,则不会使用EclipseLink。
CREATE TABLE foobar (ID BIGINT NOT NULL, grumph_id BIGINT, sample_id BIGINT, zorg_id BIGINT, PRIMARY KEY (ID))
CREATE TABLE foobar_getter (ID BIGINT NOT NULL, grumph_id BIGINT, sample_id BIGINT, zorg_id BIGINT, PRIMARY KEY (ID))
CREATE TABLE sample (ID BIGINT NOT NULL, PRIMARY KEY (ID))
CREATE TABLE zorg (ID BIGINT NOT NULL, PRIMARY KEY (ID))
CREATE TABLE grumph (ID BIGINT NOT NULL, PRIMARY KEY (ID))
ALTER TABLE foobar ADD CONSTRAINT fk_foobar_zorg FOREIGN KEY () REFERENCES ()
ALTER TABLE foobar_getter ADD CONSTRAINT fk_foobar_getter_zorg FOREIGN KEY () REFERENCES ()
ALTER TABLE foobar_getter ADD CONSTRAINT fk_foobar_getter_sample FOREIGN KEY () REFERENCES ()
休眠
Hibernate忽略我的自定义外键名称,除非我使用它们的注释。
CREATE TABLE FOOBAR (ID BIGINT NOT NULL, GRUMPH_ID BIGINT, SAMPLE_ID BIGINT, ZORG_ID BIGINT, PRIMARY KEY (ID))
CREATE TABLE FOOBARGETTER (ID BIGINT NOT NULL, GRUMPH_ID BIGINT, SAMPLE_ID BIGINT, ZORG_ID BIGINT, PRIMARY KEY (ID))
CREATE TABLE SAMPLE (ID BIGINT NOT NULL, PRIMARY KEY (ID))
CREATE TABLE ZORG (ID BIGINT NOT NULL, PRIMARY KEY (ID))
CREATE TABLE GRUMPH (ID BIGINT NOT NULL, PRIMARY KEY (ID))
ALTER TABLE FOOBAR ADD CONSTRAINT FK_FOOBAR_SAMPLE_ID FOREIGN KEY (SAMPLE_ID) REFERENCES SAMPLE (ID)
ALTER TABLE FOOBAR ADD CONSTRAINT FK_FOOBAR_GRUMPH_ID FOREIGN KEY (GRUMPH_ID) REFERENCES GRUMPH (ID)
ALTER TABLE FOOBAR ADD CONSTRAINT FK_FOOBAR_ZORG_ID FOREIGN KEY (ZORG_ID) REFERENCES ZORG (ID)
ALTER TABLE FOOBARGETTER ADD CONSTRAINT FK_FOOBARGETTER_SAMPLE_ID FOREIGN KEY (SAMPLE_ID) REFERENCES SAMPLE (ID)
ALTER TABLE FOOBARGETTER ADD CONSTRAINT FK_FOOBARGETTER_ZORG_ID FOREIGN KEY (ZORG_ID) REFERENCES ZORG (ID)
ALTER TABLE FOOBARGETTER ADD CONSTRAINT FK_FOOBARGETTER_GRUMPH_ID FOREIGN KEY (GRUMPH_ID) REFERENCES GRUMPH (ID)