JUnit + Spring + JPAを使用しています
@OneToOne 関係を持つ 2 つのエンティティがあります。
@Entity
public class Principal {
//...
@OneToOne
@JoinColumn(name = "user_id")
private User user;
//...
}
@Entity
public class User extends AbstractEntity {
//...
@OneToOne(mappedBy = "user")
private Principal principal;
//...
}
そして、JUnit テストのトランザクション内でそれらを使用することを誤解しています。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {JPATestConfig.class})
@TransactionConfiguration(defaultRollback = false)
public class JpaTest {
@PersistenceContext
protected EntityManager em;
private Long userId;
String jstl = "SELECT DISTINCT a FROM User a WHERE a.id = :id";
@Test
@Transactional
public void test() {
User user = new User();
em.persist(user);
Principal principal = new Principal();
principal.setUser(user);
em.persist(principal);
TypedQuery<User> query = em.createQuery(jstl, User.class);
query.setParameter("id", user.getId());
User user1 = query.getSingleResult();
//... In this point I have
//... user1.principal == null
}
@After
@Transactional
public void anotherTest(){
TypedQuery<User> query = em.createQuery(jstl, User.class);
query.setParameter("id", userId);
User user1 = query.getSingleResult();
//... different transaction, but still user1.principal == null
}
}
同じ jUnit @Transactional テスト内で (同じ jUnit テストクラスであっても) 作成されて永続化されたエンティティの @OneToOne パラメータを取得できないのはなぜですか?
しかし、テスト後の DB は正しく満たされたので、既存のエンティティのバインディングが成功する別のテストを開始できます。
編集
わかった、
em.persist(principal);
em.flush();
em.clear();
十分に役立ちますが、なぜバインドが機能しなかったのかまだ理解できませんanotherTest()
か?
EntityManager は transaction( test()
) の終了時に自分自身をすべてフラッシュしますね。