[英]SequenceGenerator does not work in JUnit test?
I try to test the persistence of some entities with an in-memory H2 DB but I recognized that @SequenceGenerator
will never be invoked as it should be, neither when running by build platform, nor when running it with RunAs->JUnit test in Eclipse. 我尝试使用内存中的H2 DB测试某些实体的持久性,但是我认识到
@SequenceGenerator
绝不会按其应有的方式被调用,无论是在构建平台上运行还是在Eclipse中使用RunAs-> JUnit测试运行时都不会。
What I can say for sure is that the sequences are generated inside the H2 DB. 我可以肯定地说的是,这些序列是在H2 DB内部生成的。 I can even select them when I connect to this generated H2.
连接到生成的H2时,甚至可以选择它们。 So it's definitely not a problem inside H2 but with Hibernate.
因此,H2内部绝对不是问题,而是Hibernate。 (Usually Hibernate automatically assigns an ID when persisting an Entity which needs one).
(通常,当持久存储需要一个实体时,Hibernate自动分配一个ID)。
The entity 实体
@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 [...]
}
The reference in the referencing Entity... 引用实体中的引用...
@OneToMany(mappedBy = "registry")
private List<UserData> userDataList;
The persistence unit... 持久性单元...
<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>
The invocation in JUnit test... 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())))
Other values are persisted properly. 其他值将正确保留。 Only the IDs were not generated.
仅未生成ID。 (I wonder why this test works at all for all the other values since the ID is defined as NOT NULL in the generated DB, so there should be a persistence exception or something else).
(我想知道为什么此测试对于所有其他值都完全有效,因为在生成的数据库中ID被定义为NOT NULL,所以应该存在持久性异常或其他情况)。 Any ides why the sequence generator does not generate anything (I tried
GenerationType.AUTO
as well, but no difference)? 有什么想法为什么序列生成器不生成任何东西(我也尝试了
GenerationType.AUTO
,但没有区别)?
When you are doing entityManager.persist(registry)
that is what it is going to do, store the Registry
and check all the mappings for that class. 当您要执行
entityManager.persist(registry)
,请存储Registry
并检查该类的所有映射。 It will encounter the collection of UserData
objects, but because there is no cascade
property matching the PERSIST
it will not store the UserData
objects. 它将遇到
UserData
对象的集合,但是因为没有与PERSIST
匹配的cascade
属性,它不会存储UserData
对象。
It will only store the top level Registry
object. 它只会存储顶级
Registry
对象。 If you want to change this add cascade={CascadeType.ALL}
or at least cascade={CascadeType.PERSIST}
to the @OneToMany
annotation, to tell Hibernate it also needs to check the collection for new elements and persist those. 如果要更改此设置,请在
@OneToMany
批注中添加cascade={CascadeType.ALL}
或至少cascade={CascadeType.PERSIST}
,以告诉Hibernate它还需要检查集合中的新元素并将其保留。
Or first store the UserData
elements, before storing the Registry
. 或者先存储
UserData
元素,然后再存储Registry
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.