Я использую Spring3 + JPA + Hibernate.Я попытался сохранить структуру примера похожей на мою структуру кода.Пожалуйста, прокрутите вниз до фактического вопроса.Заархивированный проект maven можно загрузить с www.esnips.com/nsdoc/da7a09c0-ce5a-4dbf-80a2-f414ea3bf333/?action=forceDL
Ниже приводится тестируемый класс.
public class ServiceImpl implements Service {
@Autowired
private DataAccessor dataAccessor;
@Autowired
private ServiceTransactions serviceTransactions;
public Foo getFoo(long id) {
return dataAccessor.getFoo(id);
}
public Foo createFoo(Foo foo) {
return dataAccessor.createFoo(foo);
}
public Bar createBar(Bar bar) {
return dataAccessor.createBar(bar);
}
@SuppressWarnings("unused")
public Foo FooifyBar(long fooId, long barId) {
Foo foo = dataAccessor.getFoo(fooId);
Bar bar = dataAccessor.getBar(barId);
return serviceTransactions.fooifyBar(fooId, barId, "Error");
}
}
Ниже приведен класс ServiceTransactions
.
public class ServiceTransactions {
@Autowired
private DataAccessor dataAccessor;
@Transactional(propagation=Propagation.REQUIRES_NEW)
public Foo fooifyBar(long fooId, long barId, String error) {
Foo foo = dataAccessor.getFoo(fooId);
Bar bar = dataAccessor.getBar(barId);
return dataAccessor.fooifyBar(foo, bar, error);
}
}
Ниже приводится реализация используемого DataAccessor
.
public class DataAccessorImpl implements DataAccessor {
@Autowired
private DBController controller;
@Transactional
public Foo getFoo(long id) {
FooDao food = controller.getFoo(id);
return convertFoodToFoo(food);
}
@Transactional
public Foo createFoo(Foo foo) {
FooDao food = new FooDao();
food.setName(foo.getName());
return convertFoodToFoo(controller.createFoo(food));
}
@Transactional
public Bar getBar(long id) {
return convertBardToBar(controller.getBar(id));
}
@Transactional
public Bar createBar(Bar bar) {
BarDao bard = new BarDao();
bard.setName(bar.getName());
return convertBardToBar(controller.createBar(bard));
}
@Transactional
public Foo fooifyBar(Foo foo, Bar bar, String error) {
return convertFoodToFoo(controller.fooBar(foo.getId(), bar.getId(), error));
}
Ниже приведена реализация DBController
public class DBControllerImpl implements DBController {
@PersistenceContext
private EntityManager em;
public FooDao getFoo(long id) {
return em.find(FooDao.class, id);
}
public FooDao createFoo(FooDao foo) {
em.persist(foo);
return foo;
}
public BarDao getBar(long id) {
return em.find(BarDao.class, id);
}
public BarDao createBar(BarDao bar) {
em.persist(bar);
return bar;
}
public FooDao fooBar(long fooId, long barId, String error) {
FooDao foo = em.find(FooDao.class, fooId);
FooedBarDao fb = new FooedBarDao();
fb.setFoo(foo);
fb.setBar(em.find(BarDao.class, barId));
fb.setError(error);
em.persist(fb);
foo.getFooedBars().add(fb);
em.merge(foo);
return foo;
}
И, наконец, тестовый класс
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="/testContext.xml")
public class TestFooBar {
@Autowired
private Service service;
Foo foo;
Bar bar;
@BeforeTransaction
public void before() {
foo = new Foo();
foo.setName("foo");
foo = service.createFoo(foo);
bar = new Bar();
bar.setName("bar");
bar = service.createBar(bar);
}
@Test
@Transactional
public void testFooingBar() {
service.FooifyBar(foo.getId(), bar.getId());
Foo foo2 = service.getFoo(foo.getId());
Assert.assertEquals(1, foo2.getFooedBars().size());
}
Теперь вопрос : тестовый случай завершается с ошибкой testFooingBar(com.test.sscce.server.TestFooBar): expected:<1> but was:<0>
в приведенной выше форме.Если я изменю метод FooifyBar
в классе ServiceImpl
и удаляю вызовы getFoo
и getBar
, тестовый сценарий пройдет без ошибок.Это означает, что изменения, сделанные с помощью fooifyBar
, не видны в методе тестирования, если getFoo
происходит до fooifyBar
.Почему это так?