2010-10-28 2 views
6

Я пишу интеграционные тесты и в одном методе тестирования хотел бы написать некоторые данные в БД, а затем прочитать их.Установить режим скрытой сессии сеанса Hibernate весной

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:applicationContext.xml"}) 
@TransactionConfiguration() 
@Transactional 
public class SimpleIntegrationTest { 

    @Resource 
    private DummyDAO dummyDAO; 

    /** 
    * Tries to store {@link com.example.server.entity.DummyEntity}. 
    */ 
    @Test 
    public void testPersistTestEntity() { 
     int countBefore = dummyDAO.findAll().size(); 
     DummyEntity dummyEntity = new DummyEntity(); 
     dummyDAO.makePersistent(dummyEntity); 

     //HERE SHOULD COME SESSION.FLUSH() 

     int countAfter = dummyDAO.findAll().size(); 

     assertEquals(countBefore + 1, countAfter); 
    } 
} 

Как вы можете видеть, между хранения и чтения данных, сессия должна быть промыты, поскольку по умолчанию FushMode является AUTO, таким образом, никакие данные не могут быть на самом деле хранится в БД.

Вопрос: Могу ли я, как некоторые набор FlushMode к ALWAYS на сессии заводе или где-нибудь еще, чтобы избежать повторения session.flush() вызова?

Все вызовы БД в DAO идут с экземпляром HibernateTemplate.

Заранее спасибо.

+1

У вас есть Spring, который вводит «SessionFactory» в тест, а в 'setUp' получает текущий' Session' и вызывает 'setFlushMode()' на нем? –

ответ

0

Этого должно быть достаточно:

@ContextConfiguration(locations="classpath:applicationContext.xml") 
public class SimpleIntegrationTest extends AbstractTransactionalJUnit4SpringContextTests { 

    @Autowired(required = true) 
    private DummyDAO dummyDAO; 

    @Test 
    public void testPersistTestEntity() { 
     assertEquals(0, dummyDAO.findAll().size()); 
     dummyDAO.makePersistent(new DummyEntity()); 
     assertEquals(1, dummyDAO.findAll().size()); 
    } 
} 

От applicationContext.xml

<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> 
    <property name="sessionFactory"> 
     <ref bean="sessionFactory"/> 
    </property> 
</bean> 

Посмотреть источник TransactionalTestExecutionListener, если у вас есть вопросы о том, как транзакции работают в этом сценарии.

Вы также можете использовать AOP (aspect oriented programming) для прокси-транзакций.

+0

К сожалению, для чего? Я действительно не понимаю, как это может решить проблему спящего сеанса спящего режима после хранения объекта. – glaz666

+0

Хотя вы аннулировали транзакцию, транзакции фактически не обрабатываются. Взгляните на класс TransactionalTestExecutionListener. Существует метод beforeTestMethod, который открывает транзакции, и метод afterTestMethod, который закрывает/откатывает. – hisdrewness

+0

Я ознакомился с классом TransactionalTestExecutionListener. И в документации четко указано, что классы, аннотированные с @Transactional, начнут и завершат транзакцию вокруг выполнения метода, и она будет откат, если класс аннотируется также с @TransactionConfiguration. Методы, о которых вы говорите, предназначены для «... для выполнения определенной настройки или разрыва кода за пределами транзакции». Поэтому, я думаю, транзакция фактически обрабатывалась по мере необходимости – glaz666

1

Попробуйте добавить следующее:

@Autowired 
private SessionFactory sessionFactory; 

@Before 
public void myInitMethod(){ 
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.ALWAYS); 
} 
1

Согласно hibernate object flushing, промывка происходит по умолчанию в следующих точках:

  • перед некоторыми выполнений запросов
  • из org.hibernate.Transaction.commit()
  • от Session.flush()

Следовательно, перед вызовом dummyDAO.findAll().size(); объекты в сеансе уже сброшены в db. Установка FlushMode в ALWAYS не требуется.

Смежные вопросы