我尝试使用内存中的H2 DB测试某些实体的持久性,但我认识到@SequenceGenerator
永远不会被调用,无论是在构建平台上运行,还是在运行RunAs时 - > Eclipse中的JUnit测试。
我可以肯定地说,序列是在H2 DB中生成的。当我连接到这个生成的H2时,我甚至可以选择它们。所以这绝对不是H2内部的问题,而是Hibernate。 (通常Hibernate会在持久化需要的实体时自动分配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;
持久单元......
<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>
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())))
其他值正确保留。仅生成了ID。 (我想知道为什么这个测试对所有其他值都有效,因为在生成的DB中ID被定义为NOT NULL,所以应该有持久性异常或其他东西)。
任何想法为什么序列生成器不生成任何东西(我也试过GenerationType.AUTO
,但没有区别)?
答案 0 :(得分:2)
当您正在执行entityManager.persist(registry)
时,请存储Registry
并检查该类的所有映射。它将遇到UserData
个对象的集合,但由于没有cascade
属性与PERSIST
匹配,因此它不会存储UserData
个对象。
它只存储顶级Registry
对象。如果要更改此cascade={CascadeType.ALL}
或至少cascade={CascadeType.PERSIST}
添加到@OneToMany
注释,要告诉Hibernate它还需要检查集合中的新元素并保留它们。
或者在存储UserData
之前首先存储Registry
元素。