I'm trying to build some tests around some audited entities. My problem is that envers only audits on a transaction commit.
I need to create/edit some test objects, commit the transaction and then check the revisions.
What's the best approach to integration testing with envers?
Update: Here's a really bad, non-deterministic test class of what I want to achieve. I would prefer to do this without relying on the order of the test methods
First create an account and account_transaction in a single transaction. Both audited entries are for revision 1.
Second updated the account_transaction in a new transaction. The audited entry is at revision 2.
Third, load the audited account at revision 1 and do something with it.
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/testApplicationContext.xml"})
public class TestAuditing {
@Autowired
private AccountDao accountDao;
@PersistenceContext
private EntityManager entityManager;
@Test
@Rollback(false)
public void first() {
Account account = account("Test Account", "xxxxxxxx", "xxxxxx");
AccountTransaction transaction = transaction(new Date(), Deposit, 100, "Deposit");
account.setTransactions(newArrayList(transaction));
accountDao.create(account);
}
@Test
@Rollback(false)
public void second() {
Account account = accountDao.getById(1L);
AccountTransaction transaction = account.getTransactions().get(0);
transaction.setDescription("Updated Transaction");
accountDao.update(account);
}
@Test
public void third() {
AuditReader reader = AuditReaderFactory.get(entityManager);
List<Number> accountRevisions = reader.getRevisions(Account.class, 1L);
//One revision [1]
List<Number> transactionRevisions = reader.getRevisions(AccountTransaction.class, 1L);
//Two revisions [1, 2]
Account currentAccount = accountDao.getById(1L);
Account revisionAccount = (Account) reader.createQuery().forEntitiesAtRevision(Account.class, 1).getSingleResult();
System.out.println(revisionAccount);
}
DbResetRule
- my idea is to avoid using@Transactional
JUnit tests and just let your code commit and rollback transactions. Obviously this makes tests non-repeatable and fragile. But instead of rolling back the changes I'm proposing dumping the database and restoring it before/after each test. Code is in Scala, but this is just a general idea. Let me know if this is what you are looking for so I will elaborate a little bit more in separate answer. – Roar@Transactional
you don't have to do anything manually. Looks like you are already doing it. But when you remove@Transactional
from test, you cannot simply useEntityManager
in test. Either wrap its access in a transactional bean or useTransactionTemplate
. – Roar