In regelmäßigen Abständen versuche ich dieses Problem zu lösen. Meistens habe ich in der Zwischenzeit vergessen, wo ich das Problem das letzte Mal gelöst habe. Die Codestellen vermehren sich zwar, trotzdem wird es Zeit die paar Zeilen Code festzuhalten.
Die einfachste Möglichkeit ist die Testklasse von AbstractTransactionalJUnit4SpringContextTests abzuleiten. Leider funktioniert das nur, wenn auch nur genau ein JpaTransactionManager als Spring-Bean existiert. In Systemen mit unterschiedlichen Datenquellen ist damit nichts zu machen.
Ist keine Ableitung erwünscht oder existieren mehr als ein TransactionManager, verwende ich meistens diese Lösung. Grundsätzlich ist das genau der Code, der in den zwei Klassen
verwendet wird.
@ContextConfiguration("classpath*:application-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class
})
@Transactional
@TransactionConfiguration
(transactionManager = "transactionManagerTarget",
defaultRollback = true)
public class TransactionTest{
@Resource(name="transactionalClass")
TransactionalClass transactionalClass;
@Transactional
@Test
public void testTransaction(){
...
}
}
Natürlich kann man mit dem TransactionManager auch direkt eine Transaction öffnen und schließen. Dazu werden auch keine Annotations benötigt.
@Resource(name="transactionManager")
JpaTransactionManager transactionManager;
...
DefaultTransactionAttribute transactionAttribute =
new DefaultTransactionAttribute (TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager
.getTransaction(transactionAttribute);
Mit diesen drei Möglichkeiten sollten eigentlich alle Fälle abgedeckt sein. Die beste Quellen dazu war natürlich auf StackOverflow.