2010-10-28 10 views
6

Sto scrivendo i test di integrazione e in un metodo di prova vorrei scrivere alcuni dati su DB e quindi leggerlo.Imposta la modalità flush della sessione di sospensione in primavera

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

Come si può vedere tra la memorizzazione e la lettura dei dati, la sessione deve essere lavata perché il valore predefinito è FushModeAUTO quindi i dati non possono essere effettivamente memorizzati nel DB.

Domanda: Posso in qualche modo impostare FlushMode-ALWAYS in fabbrica di sessione o da qualche altra parte per evitare di ripetere session.flush() chiamata?

Tutte le chiamate DB in DAO vanno con l'istanza HibernateTemplate.

Grazie in anticipo.

+1

Si può avere Spring iniettare 'SessionFactory' nel test, e nel' setUp' ottenere l'attuale 'Session' e chiamare' setFlushMode() 'su di esso? –

risposta

0

Questo dovrebbe essere sufficiente:

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

Da applicationContext.xml

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

Vista la fonte di TransactionalTestExecutionListener se avete domande su come le transazioni funzionano in questo scenario.

È inoltre possibile utilizzare AOP (aspect oriented programming) per le transazioni proxy.

+0

Scusa, sufficiente per cosa? In realtà non capisco come questo possa risolvere il problema di avere una sessione di ibernazione svuotata dopo aver archiviato l'oggetto. – glaz666

+0

Mentre hai annotato di essere transazionale, nessuna transazione viene effettivamente gestita. Dai un'occhiata alla classe TransactionalTestExecutionListener. C'è un beforeTestMethod che apre le transazioni e un afterTestMethod che chiude/rollback. – hisdrewness

+0

Ho dato un'occhiata alla classe TransactionalTestExecutionListener. E la documentazione afferma chiaramente che le classi annotate con @Transactional inizieranno e finiranno la transazione intorno all'esecuzione del metodo e verrà annullata se la classe viene annotata anche con @TransactionConfiguration. I metodi che stai menzionando sono per "... essere in grado di eseguire determinati set up o di eliminare il codice al di fuori di una transazione". Quindi immagino che la transazione sia effettivamente gestita come necessario – glaz666

1

Prova ad aggiungere il seguente:

@Autowired 
private SessionFactory sessionFactory; 

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

Secondo hibernate object flushing, vampate di calore avviene per default nei seguenti punti:

  • prima di alcune esecuzioni di query
  • da org.hibernate.Transaction.commit()
  • da Session.flush()

Pertanto, prima di chiamare dummyDAO.findAll().size();, gli oggetti nella sessione sono già scaricati in db. L'impostazione di FlushMode su ALWAYS non è necessaria.

Problemi correlati