我嘗試使用內存中的H2數據庫來測試某些實體的持久性,但是我認識到@SequenceGenerator
永遠不會被調用,因爲它應該是這樣,既不是在通過構建平臺運行時,也不是在運行時使用RunAs-> JUnit test in蝕。SequenceGenerator在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沒有生成。 (我想知道爲什麼這個測試對所有其他值都起作用,因爲在生成的數據庫中將ID定義爲NOT NULL,所以應該存在持久性異常或其他內容)。 任何ides爲什麼序列發生器不會產生任何東西(我也試過GenerationType.AUTO
,但沒有區別)?
因爲它沒有被告知這樣做。您正在堅持'Registry',但'UserData'對象的集合沒有cascade屬性。這意味着只有最高級別的Registry纔會被保存,而不是單個的UserData對象。數據庫中沒有任何內容,從'entityManager.find'方法返回的是從數據庫中存儲在第一級緩存中的對象。如果你在'find'之前執行'entityManager.clear()',你將得到一個沒有'UserData'對象的'Registry'實例。 –