【问题标题】:Hibernate @SequenceGenerator not globalHibernate @SequenceGenerator 不是全局的
【发布时间】:2014-02-08 13:53:16
【问题描述】:

我有两个使用生成值的实体类

@Entity
@SequenceGenerator(allocationSize = 1, initialValue = 1000, name = "idgen")
public class Ent1 {
    @Id
    @GeneratedValue(generator = "idgen")
    private Long id;

    ...
}

@Entity
public class Ent2 {
    @Id
    @GeneratedValue(generator = "idgen")
    private Long id;

    ...
}

问题是如果不放行

@SequenceGenerator(allocationSize = 1, initialValue = 1000, name = "idgen")

两个实体上我得到一个错误:

Caused by: org.hibernate.AnnotationException: Unknown Id.generator: idgen

But the JPA spec says that the scope of the @SequenceGenerator is 'global' and can be reused across entities.

我错过了什么?

【问题讨论】:

    标签: hibernate jpa annotations sequence-generators


    【解决方案1】:

    这似乎是 Hibernate JPA 实现中的一个错误,因为它可以按照您对 EclipseLink JPA 实现的期望工作(我对两者都进行了测试)。使用 Hibernate,它只有在我使用 orm.xml 在应用程序级别声明 SequenceGenerator 时才有效(假设您使用的是 JPA EntityManager)。如果您还没有 orm.xml,则它位于您的 persistence.xml 旁边。

    这是在 orm.xml 中声明序列生成器的示例:

    <?xml version="1.0" encoding="UTF-8"?>
    <entity-mappings
      xmlns="http://java.sun.com/xml/ns/persistence/orm"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
      version="2.0">
    
      <sequence-generator name="idgen" allocation-size="1" initial-value="1000" />
    
    </entity-mappings>
    

    那么你就不必在每个类中声明SequenceGenerator了。

    【讨论】:

    • 我尝试将 @SequenceGenerator 添加到 package-info.java 但随后出现编译器错误,提示此类型的注解不适用于此处。
    • package-info.java 在我在 Eclipse 中编译时工作,但我没有尝试只使用 javac,现在我发现这是无效的(有趣的是 Eclipse 允许这样做)。相反,您必须使用 orm.xml 来声明序列生成器。请参阅我的更新答案。
    • 是否还有一种方法可以覆盖默认的序列生成器,因此生成的值不需要每个类中的显式引用?
    【解决方案2】:

    规范的以下部分对我来说确实很奇怪。

    生成器名称的范围对于持久性单元是全局的(跨所有生成器类型)。

    我会像你一样解释它:一个生成器可以在一个位置指定,并在同一个持久性单元的任何地方重用。好像当前的Hibernate实现没有考虑到这句话。

    是否有任何 JPA/Hibernate 规范专家可以帮助解释这句话?

    【讨论】:

      【解决方案3】:

      复制

      @SequenceGenerator(allocationSize = 1, initialValue = 1000, name = "idgen")
      

      到 Ent2 应该可以工作,
      您可以参考https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/seq-generator.html了解更多详情

      【讨论】:

        【解决方案4】:

        过去,Hibernate 为每个实体限定序列,然后 JPA 说这应该是全局的,因此为了允许两者,引入了一个设置来控制它。您可以通过将hibernate.jpa.compliance.global_id_generators 设置为true 来启用全局范围。详情另见文档:https://docs.jboss.org/hibernate/orm/5.5/userguide/html_single/Hibernate_User_Guide.html#configurations-jpa-compliance

        【讨论】:

        • 这里要理解的重要一点是,此标志将通过使名称/配置全局可用来启用重用 SequenceGenerator Definitionper Entity 仍然创建了一个 separate 生成器(即使在 @MappedSuperclass 上使用)!!当您尝试在多个实体之间共享一个具有已定义 allocationSize &gt; 1 的生成器时,可能会发生混淆。如果不滚动您自己的发电机 AFAIK,这是不可能的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-24
        相关资源
        最近更新 更多