2016-08-19 13 views
0

私はメモリ内のH2 DBを使っていくつかのエンティティの永続性をテストしようとしていますが、@SequenceGeneratorは、ビルドプラットフォームで実行しているときでもRunAs-> JUnitテストでも実行していないときEclipse。SequenceGeneratorはJUnitテストでは機能しませんか?

私が言うことができるのは、シーケンスがH2 DB内で生成されていることです。私はこの生成されたH2に接続するときにそれらを選択することさえできます。 H2の内部では問題ありませんが、Hibernateでは問題ありません。 (通常、Hibernateは、Entityを必要とするEntityを永続化するときに自動的に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が生成されたDBにNOT NULLとして定義されているので、このテストが他のすべての値に対して何故機能するのか不思議です。そのため、永続性例外などがあるはずです)。 シーケンスジェネレータが何も生成しない理由は何ですか(私もGenerationType.AUTOを試しましたが、違いはありません)?

+0

そうするように言われていないので。 'Registry'を永続していますが、' UserData'オブジェクトのコレクションにはカスケードプロパティはありません。つまり、トップレベルの 'Registry'だけが保存され、個々の' UserData'オブジェクトは保存されません。データベースに何もありません。あなたが 'entityManager.find'メソッドから返すものは、データベースからではなく、第1レベルのキャッシュに格納されているオブジェクトです。 'find'の前に' entityManager.clear() 'を実行すると、' UserData'オブジェクトのない 'Registry'インスタンスが得られます。 –

答えて

2

entityManager.persist(registry)を実行しているときは、Registryを保存して、そのクラスのすべてのマッピングを確認してください。 UserDataオブジェクトのコレクションに遭遇しますが、PERSISTに一致するcascadeプロパティがないため、UserDataオブジェクトは保存されません。

トップレベルのRegistryオブジェクトのみが格納されます。これを変更したい場合は、または少なくともcascade={CascadeType.PERSIST}@OneToManyアノテーションに追加して、Hibernateに伝えるために、新しい要素のコレクションをチェックしてそれらを保持する必要があります。

Registryを保存する前に、最初にUserData要素を保存してください。

+0

ありがとうございます。 – Bevor

関連する問題