简体   繁体   English

SequenceGenerator在JUnit测试中不起作用?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM