2

我正在为连接到数据库的应用程序的服务器部分编写 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而不是数据库的默认值。

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

4

2 回答 2

2

不,您不能更改整个持久性单元的默认值,但您可以覆盖 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 文档中找到有关覆盖映射的更多信息。

于 2012-10-25T18:51:12.163 回答
0

确保SEQUENCE在数据库中做。

例子 :

CREATE SEQUENCE example_sq START WITH 50 INCREMENT BY 50;   

使用strategy=GenerationType.SEQUENCE. 这里有更多参考。

@Id
@SequenceGenerator(name = "sequence", sequenceName = "sequence", allocationSize=50)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="sequence")
protected Integer id;
于 2012-10-25T07:17:29.443 回答