5

我设置了@Transactional JUnit 测试,我想将一些测试数据保存到数据库中,并测试关联是否正确。但是,在测试关联时,它们总是评估为 null,即使它在非事务测试中确实有效。

我使用 @Before 注释保留了两个对象:

@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);
}

在测试中访问这两个对象时,我得到了正确的实例:

    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 会话中。比你创建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 回答