Java SequenceGenerator在JUnit测试中不工作?
我试图用内存中的H2 DB测试某些实体的持久性,但我认识到,Java SequenceGenerator在JUnit测试中不工作?,java,hibernate,jpa,junit,h2,Java,Hibernate,Jpa,Junit,H2,我试图用内存中的H2 DB测试某些实体的持久性,但我认识到,@SequenceGenerator将永远不会被调用,无论是在构建平台上运行时,还是在Eclipse中使用RunAs->JUnit测试运行时 我可以肯定的是,序列是在h2db内部生成的。我甚至可以在连接到生成的H2时选择它们。因此,H2内部肯定没有问题,但Hibernate有问题。 (通常Hibernate会在持久化需要ID的实体时自动分配ID) 实体 @Entity @Table(name = "HOUSE_USERDATA") pu
@SequenceGenerator
将永远不会被调用,无论是在构建平台上运行时,还是在Eclipse中使用RunAs->JUnit测试运行时
我可以肯定的是,序列是在h2db内部生成的。我甚至可以在连接到生成的H2时选择它们。因此,H2内部肯定没有问题,但Hibernate有问题。
(通常Hibernate会在持久化需要ID的实体时自动分配ID)
实体
@Entity
@Table(name = "HOUSE_USERDATA")
public class UserData {
@Id
@Column(name = "HU_ID")
@GeneratedValue(generator = "SEQ_HOUSE_USERDATA", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(sequenceName = "SEQ_HOUSE_USERDATA", name = "SEQ_HOUSE_USERDATA", allocationSize = 2)
private Long huId;
@Column(name = "HU_DATA")
@Size(max = 1000)
private String m_data;
@ManyToOne
@JoinColumn(name = "HR_ID")
private Registry m_registry;
//more code [...]
}
引用实体中的引用
@OneToMany(mappedBy = "registry")
private List<UserData> userDataList;
@OneToMany(mappedBy=“注册表”)
私有列表userDataList;
持久化单元
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.foo.bar.all.entity</class>
<!-- all entity references -->
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url"
value="jdbc:h2:inmemory;INIT=runscript from 'classpath:testscripts/drop_h2.sql'\;runscript from 'classpath:testscripts/create.sql'"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.use_sql_comments" value="true" />
</properties>
</persistence-unit>
org.hibernate.ejb.HibernatePersistence
com.foo.bar.all.entity
假的
JUnit测试中的调用
Registry registry = new Registry();
registry.setClientId("clientId");
List<UserData> userDataList = new ArrayList<>();
UserData userData1 = new UserData();
userData1.setData("User defined data 1.");
userData1.setRegistry(registry);
UserData userData2 = new UserData();
userData2.setData("User defined data 2.");
userData2.setRegistry(registry);
userDataList.add(userData1);
userDataList.add(userData2);
registry.setUserDataList(userDataList);
entityManager.persist(registry);
Registry result = entityManager.find(Registry.class, "clientId");
//MUST NOT BE NULL, BUT IS NULL
assertThat(result.getUserDataList().get(0).getId(), is(not(nullValue())))
Registry Registry=new Registry();
registry.setClientId(“clientId”);
List userDataList=new ArrayList();
UserData userData1=新的UserData();
setData(“用户定义数据1”);
userData1.setRegistry(注册表);
UserData userData2=新的UserData();
setData(“用户定义数据2”);
userData2.setRegistry(注册表);
添加(userData1);
添加(userData2);
registry.setUserDataList(userDataList);
entityManager.persist(注册表);
Registry result=entityManager.find(Registry.class,“clientId”);
//不能为NULL,但为NULL
断言(result.getUserDataList().get(0.getId())是(而不是(nullValue()))
其他值被正确持久化。只有ID没有生成。(我想知道为什么这个测试对所有其他值都有效,因为ID在生成的DB中定义为NOTNULL,所以应该存在持久性异常或其他东西)。
序列生成器为什么不生成任何东西(我也尝试了
GenerationType.AUTO
,但没有区别)?当您执行entityManager.persist(registry)
这就是它要做的,存储注册表
并检查该类的所有映射。它将遇到UserData
对象的集合,但由于没有与PERSIST
匹配的cascade
属性,因此它不会存储UserData
对象
它将只存储顶级注册表
对象。如果您想将此添加cascade={CascadeType.ALL}
或至少cascade={CascadeType.PERSIST}
到@OneToMany
注释,告诉Hibernate它还需要检查集合中的新元素并将其持久化
或者先存储
用户数据
元素,然后再存储注册表
当您执行entityManager.persist(registry)
操作时,存储registry
并检查该类的所有映射。它将遇到UserData
对象的集合,但由于没有与PERSIST
匹配的cascade
属性,因此它不会存储UserData
对象
它将只存储顶级注册表
对象。如果您想将此添加cascade={CascadeType.ALL}
或至少cascade={CascadeType.PERSIST}
到@OneToMany
注释,告诉Hibernate它还需要检查集合中的新元素并将其持久化
或者先存储
用户数据
元素,然后再存储注册表
因为它没有被告知这样做。您正在持久化注册表
,但是用户数据
对象的集合没有级联属性。这意味着只保存顶级注册表
,而不保存单个用户数据
对象。数据库中没有任何内容,从entityManager.find方法返回的是存储在一级缓存中的对象,而不是数据库中的对象。如果在find
之前执行entityManager.clear()
,您将得到一个Registry
实例,其中没有UserData
对象。因为没有告诉它这样做。您正在持久化注册表
,但是用户数据
对象的集合没有级联属性。这意味着只保存顶级注册表
,而不保存单个用户数据
对象。数据库中没有任何内容,从entityManager.find方法返回的是存储在一级缓存中的对象,而不是数据库中的对象。如果在find
之前执行entityManager.clear()
,则会得到一个Registry
实例,其中没有UserData
对象。