메모리 내 H2 DB를 사용하여 일부 엔티티의 지속성을 테스트하려고 시도했지만 빌드 플랫폼으로 실행 중일 때도 아니고 RunAs-> JUnit 테스트로 실행할 때도 @SequenceGenerator
이 호출되지 않습니다. 식.SequenceGenerator가 JUnit 테스트에서 작동하지 않습니까?
내가 말할 수있는 것은 시퀀스가 H2 DB 내부에서 생성된다는 것입니다. 이 생성 된 H2에 연결할 때도 선택할 수 있습니다. H2에서는 분명히 문제는 아니지만 최대 절전 모드입니다. (보통 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
도 시도했지만 차이는 없었습니다)?
그렇게하지 않기 때문에. 당신은'Registry'를 지속하고 있지만'UserData' 객체들의 컬렉션은 캐스케이드 속성을 가지고 있지 않습니다. 즉 최상위 'Registry'만이 저장되고 개별'UserData' 객체는 저장되지 않는다는 것을 의미합니다. 데이터베이스에 아무것도 없다. 당신이'entityManager.find' 메쏘드에서 반환하는 것은 데이터베이스가 아닌 첫 번째 레벨 캐시에 저장된 객체이다. 'find' 전에'entityManager.clear()'를하면'UserData' 객체가없는'Registry' 인스턴스를 얻을 수 있습니다. –