【问题标题】:Can I change default (AUTO) value for GenerationType in @GeneratedValue for persistence unit?我可以更改持久性单元的 @GeneratedValue 中 GenerationType 的默认 (AUTO) 值吗?
【发布时间】:2012-10-15 07:01:19
【问题描述】:

我正在为连接到数据库的应用程序的服务器部分编写 junit 测试。我们通常的策略是放入覆盖默认文件的src/test/resources/META-INF/persistence.xml 文件,这样测试就不会连接到Oracle 数据库,而是连接到hsqldb。

这是我的问题 - 其中一个实体的字段定义如下:

@Id
@Column(name = "ID", nullable = false)
@SequenceGenerator(name="sequence", sequenceName="sequence")
@GeneratedValue(generator="sequence")
protected Integer id;

在应用程序的标准运行期间,它工作正常 - 我没有为 @GeneratedValue 定义特定策略,因此它默认为 GenerationType.AUTO,根据 http://docs.oracle.com/javaee/5/api/javax/persistence/GenerationType.html#AUTO ,它让持久性提供者根据哪个策略决定使用哪种策略数据库位于下面,因为通常它是 Oracle 并且 Oracle 的默认生成器策略是 GenerationType.SEQUENCE

但是当我运行测试时,我得到:

[junit] Testcase: xxx.TestCase took 0 sec
[junit]     Caused an ERROR
[junit] "xxx.Entity.id" declares generator name "sequence", but uses the AUTO generation type.  The only valid generator names under AUTO are "uuid-hex" and "uuid-string".

根据Hibernate @generatedvalue for HSQLDB中的评论,hsqldb的默认策略是GenerationType.IDENTITY

显而易见的解决方案是将strategy=GenerationType.SEQUENCE 添加到实体的字段定义中,但是 1)更改工作代码以适应测试用例通常是不好的做法 2)我没有完全访问或更改此实体的权限。所以假设我无法改变我的下一个预感是在我们的测试META-INF/persistence.xml 中的persistece-unit 定义中放置一些属性,这将告诉Hibernate 将默认生成器策略设置为SEQUENCE 而不是数据库的默认值。

我可以这样做吗,如果可以,我该怎么做,如果不能,我还能做什么?

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    不,您不能更改整个持久性单元的默认值,但您可以覆盖 XML 映射中的策略:

    @Entity
    public class EntityA {
        @Id
        @GeneratedValue
        protected Integer id;
        ...
    }
    

    META-INF 中的 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 http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0">
        <package>somepackage.somewhere</package>
        <entity class="EntityA" metadata-complete="false" access="FIELD">
            <attributes>
                <id name="id">
                    <generated-value strategy="SEQUENCE"/>
                 </id>
            </attributes>
        </entity>
    </entity-mappings>
    

    在上面的例子中 metadata-complete="false" 意味着那些没有被覆盖的注解仍然适用。文件被完整粘贴,因为人们经常难以从多个来源复制粘贴。

    有关覆盖映射的更多信息,例如可以从Hibernate documentation 中找到。

    【讨论】:

      【解决方案2】:

      确保在数据库中做SEQUENCE

      例子:

      CREATE SEQUENCE example_sq START WITH 50 INCREMENT BY 50;   
      

      使用strategy=GenerationType.SEQUENCEHere 更多参考。

      @Id
      @SequenceGenerator(name = "sequence", sequenceName = "sequence", allocationSize=50)
      @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="sequence")
      protected Integer id;
      

      【讨论】:

      • 是的,正如我所说 - 这将是显而易见的解决方案,正如我所说 - 我不能简单地这样做,因为我无权访问实体。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多