5

@Transactional JUnit テストをセットアップしており、いくつかのテスト データをデータベースに保持し、関連付けが正しいかどうかもテストしたいと考えています。ただし、アソシエーションをテストする場合、非トランザクション テストで機能する場合でも、常に null と評価されます。

@Before アノテーションを使用して 2 つのオブジェクトを永続化します。

@Before
public void testData() {
    TestObjectOne o = new TestObjectOne();
    o.setName("One");
    repo.saveEntity(o); //autowired

    TestObjectTwo t = new TestObjectTwo();
    t.setOne(o);
    t.setName("Two");
    repo.saveEntity(t);
}

テストでこれら 2 つのオブジェクトにアクセスすると、正しいインスタンスが得られます。

    TestObjectOne o = repo.getOneByName("One");
    TestObjectOne t = repo.getTwoByName("Two");

と の間の関連付けをチェックするto、その関連付けを明示的に定義したため、正しい参照が得られます。

    Assert.assertNotNull(t.getOne());

しかし、逆にチェックすると、オブジェクトoは正しく更新されません。

    Assert.assertNotNull(o.getTwos());

関連付けは、ドメイン オブジェクトで次のように定義されます。

One

   @OneToMany(mappedBy = "one", fetch = FetchType.EAGER)
   private List<Two> twos;

Two

  @ManyToOne(optional = false)
  private One one;

テストを @Transactional として実行しないと、うまく動作します。

@Before メソッドの代わりにテスト内にエンティティを保存して編集 しても、違いはありません。

4

2 に答える 2

4

保存後、アサーションのテストオブジェクトをロードする前に、現在のセッションをフラッシュしてクリアする必要があります。

インスタンスを保存すると、TestObjectOne oそのインスタンスはHibernateセッションに保持されます。Than Youを作成TestObjectTwo tして参照を追加しo、保存して、このインスタンスもHibernateセッションに保持されるようにします。get Hibernateを呼び出すときよりも、実際の状態を反映するように更新せずに、以前に作成したインスタンスを取得します。したがって、ロードする前にセッションをフラッシュしてクリアする必要があります。セッションL1キャッシュが空になり、エンティティが正しくロードされます。

public class MyTest {

    @Before
    public void setUp() {

        TestObjectOne o = new TestObjectOne();
        o.setName("One");
        repo.saveEntity(o); //autowired

        TestObjectTwo t = new TestObjectTwo();
        t.setOne(o);
        t.setName("Two");
        repo.saveEntity(t);

        /* push all changes to current transaction*/
        repo.getSessionFactory().getCurrentSession().flush();
        /* clean current session, so when loading objects they'll
           be created from sratch and will contain above changes */
        repo.getSessionFactory().getCurrentSession().clear();
    }

    @Test
    public void test() {
        TestObjectOne o = repo.getOneByName("One");
        TestObjectOne t = repo.getTwoByName("Two");

        Assert.assertNotNull(t.getOne());
        Assert.assertNotNull(o.getTwos());
    }
}
于 2011-07-15T11:14:11.107 に答える
0

@Transactional アノテーションはテスト後にロールバックをトリガーするため、結果はデー​​タベースに保持されません。

データを永続化する必要があるテストでは、アノテーションに加えて@Rollback(false)アノテーションを追加できます@Transactional

于 2011-07-13T15:29:22.857 に答える