2016-08-19 9 views
0

메모리 내 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도 시도했지만 차이는 없었습니다)?

+0

그렇게하지 않기 때문에. 당신은'Registry'를 지속하고 있지만'UserData' 객체들의 컬렉션은 캐스케이드 속성을 가지고 있지 않습니다. 즉 최상위 'Registry'만이 저장되고 개별'UserData' 객체는 저장되지 않는다는 것을 의미합니다. 데이터베이스에 아무것도 없다. 당신이'entityManager.find' 메쏘드에서 반환하는 것은 데이터베이스가 아닌 첫 번째 레벨 캐시에 저장된 객체이다. 'find' 전에'entityManager.clear()'를하면'UserData' 객체가없는'Registry' 인스턴스를 얻을 수 있습니다. –

답변

2

수행 할 작업이 entityManager.persist(registry) 일 때 Registry을 저장하고 해당 클래스의 모든 매핑을 확인하십시오. UserData 개체 컬렉션이 발생하지만 PERSIST과 일치하는 cascade 속성이 없으므로 UserData 개체는 저장되지 않습니다.

최상위 레벨 Registry 개체 만 저장합니다. 이 값을 변경하려면 cascade={CascadeType.ALL} 또는 적어도 cascade={CascadeType.PERSIST}@OneToMany 주석에 추가하고, Hibernate에게 알려주려면 새로운 요소를위한 콜렉션을 검사하고이를 유지해야한다.

또는 Registry을 저장하기 전에 먼저 UserData 개의 요소를 저장하십시오.

+0

감사합니다. – Bevor

관련 문제