当前位置: 首页 > 知识库问答 >
问题:

使用EclipseLink和Hibernate(JPA2.1)生成模式-忽略@ForeignKey

邢浩邈
2023-03-14

我正在测试JPA2。1和新的“模式生成”html" target="_blank">功能。为此,我在HyperSQL数据库下测试了两个实现:

  • Eclipse Link 2.5.2-M1,它是参考实现。
  • Hibernate4.3

我对实现没有任何偏好(甚至对性能也没有偏好)。我测试了EclipseLink,因为它是第一个JPA2。1实现可用,但现在,Hibernate4.3在这里,JPA2也在这里。1合规。我唯一想要的是获得独立于JPA提供者的东西——除了配置(如缓存、日志、静态编织等)。

对于模式生成,我感兴趣的有几个方面:

  • 我对Eclipse Link的默认命名策略不满意:上层大小写实体类名或字段/属性名,使其不可读。我不扩展会话自定义程序(我试过一次,我认为把注释放起来更容易,更不危险...)。
  • 我不喜欢查询中的大小写;这是我的个人偏好,但我在linux上也有MySQL的问题,因为它们不遵循标识符,关键字不区分大小写,除非你SQL习惯用法引用它们。
  • 默认情况下,Hibernate也好不到哪里去,但是命名策略可以使用改进命名策略来改进。可悲的是,它没有用显式名称命名外键:FK_8gc2pk9u5bsbhpi91x93c77o不是显式的,而fk_foobar_sample是显式的。

因此,我添加了@Table@JoinColumn@Column注释来强制我的命名策略,现在我被外键生成阻止了,外键生成的支持似乎很差(当符合JPA2.1时):

  • Hibernate希望我使用@org.hibernate.annotations.ForeignKey,为此我需要注释字段或属性。但它是一个Hibernate注释,因此不符合JPA2.1。
  • Eclipse Link永远不会生成外键约束,除非我把一个@JoinCol一身和一个外键@ForeignKey(name="...")。但是当它生成外键时,定义丢失了(即:ALTER TABLE页脚栏ADD CONSTRAINTfk_foobar_zorgFOREIGN KEY()REFERENCES()),而根据Javadoc它应该存在。
  • @ManyToOne是Hibernate生成外键所必需的(抛出异常),而Eclipse Link则不需要。我不明白为什么需要它:如果引用的类型被注释为@Entity,那么当它可以完美地从引用的类推导。
  • 如果没有设置外键,Eclipse Link不会为带注释的字段生成外键约束。

我应该怎么做才能以纯JPA2.1的方式完成这项工作?

因为我的示例案例太大,无法放在Stackoverflow上,所以您会发现一个包含4 maven 3项目的归档文件:

  • jpa2.1-父项目(POM)
  • jpa2.1-eclipselink: Eclipse Link 2.5.2-M1,带有@Table@JoinColiv注释。
  • jpa2.1-eclipselink-默认: Eclipse Link 2.5.2-M1没有@Table@JoinColiv注释和默认命名策略
  • jpa2.1-hibernate:带有自定义名称的Hibernate 4.3。
  • jpa2.1-hibernate-down: Hibernate 4.3不带@Table@JoinColiv注释和默认命名策略

只需在根项目上运行mvn test,然后运行您喜欢的任何diff工具:

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

POM还可以使用Eclipse的Maven插件导入Eclipse(在开普勒上测试)。

作为参考,这里是不同SQL文件的结果(删除文件也是错误的,但只是因为约束名称没有重载)。

日蚀链接

如您所见,外键约束在语法上是无效的;并且在fobar上缺少两个约束(一个到zorg,另一个到grumph)。

    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  ()

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 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)

冬眠

Hibernate忽略我的自定义外键名,除非我使用它们的注释。

    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 grumph (id bigint not null, primary key (id))
    create table sample (id bigint not null, primary key (id))
    create table zorg (id bigint not null, primary key (id))
    alter table foobar add constraint FK_45nw30c81ae209hokgmrs9gyy foreign key (grumph_id) references grumph
    alter table foobar add constraint FK_b3pwyt79opfaopbjwaf23h11f foreign key (sample_id) references sample
    alter table foobar add constraint hb_foobar_zorg foreign key (zorg_id) references zorg
    alter table foobar_getter add constraint FK_1s2755a8mgvune6lhpfw8cifr foreign key (grumph_id) references grumph
    alter table foobar_getter add constraint FK_slbhet4s26lh9ma4vh63ltctj foreign key (sample_id) references sample
    alter table foobar_getter add constraint hb_foobar_getter_zorg foreign key (zorg_id) references zorg

共有1个答案

殷永嘉
2023-03-14

似乎我遇到了Hibernate HHH-8783的错误(我将再次评论它,因为这不适用于@JoinTable@OneTo多/@ManyTo多)和Eclipse Link 425656,所以我的问题不再相关。

我仍然需要理解的最后一件事(但它超出了我最初问题的范围)是为什么我在Hibernate中为@OneTo很多生成了一个唯一的密钥,而不是在Eclipse Link中。

 类似资料:
  • 我们有一个实体树,由一个父实体组成,该父实体与一个子实体具有多对多关系,如下所述(在kotlin中)。为什么hibernate似乎忽略了与实体关系关联的FetchMode? 观察到的行为:在父级FetchMode的JpaRepository上执行findAll时。忽略SUBSELECT,Hibernate为每个父级触发一个新的选择来获取子级。 预期行为:在父节点的JpaRepository上执行f

  • 我想知道如何使用Maven和Eclipselink 2.5生成静态元模型。通过将这些行添加到pom中,它工作得很好。运行Eclipselink 2.4时使用xml。 但2.4版之后似乎发生了一些变化,原因如下: 你们能帮帮我吗 B. R.

  • 问题内容: 我正在使用Hiberbnate 3.1.3。我有如下映射,当我尝试将记录插入TEST_TABLE时,出现异常:’线程“ main” org.hibernate.exception.SQLGrammarException中的异常:无法获取增量生成器的初始值” 我在cfg.xml中设置了以下默认模式,因为我需要在应用程序中使用OTHER_SCHEMA中的表。 在上述情况下,这似乎是一个Hi

  • 有没有一种方法可以忽略使用mapstruct在此代码示例中第三种方法的映射器的生成?

  • 在JavaEE环境中,我将JPA2.1实现与EclipseLink一起使用, CarColor转换器: persistence.xml > 当我在persistence.xml文件上注释转换器的声明,并试图将我的实体持久化到数据库中时,会出现这样的错误:“请确保转换器类名正确,并且存在于持久化单元定义中。”并且没有编译时间异常,只有一个非常明确的警告:

  • 问题内容: 这是我的实体: 这是我获得人员名单的方式: 如果我正确理解提取图,则它必须仅加载我指定的那些字段。但是,字段“ birthDate”也已加载。此外,我看到在hibernateSQL查询中选择了4列。 如何解决?我使用hibernate 5.1.0作为JPA提供程序。 问题答案: 实体图旨在控制延迟或渴望加载哪些关系(例如,一对一,一对多等)。它们可能不适用于加载各个列(取决于提供程序)