use of org.eclipse.persistence.testing.models.jpa.advanced.BillLineItem in project eclipselink by eclipse-ee4j.
the class AdvancedJPAJunitTest method testTransparentIndirectionQuerySessionReset.
/**
* Bug 489898 - RepeatableWriteUnitOfWork linked by QueryBasedValueHolder in shared cache in specific scenario
*
* Complex scenario: In a transaction, associate an existing object to a new object, refresh the existing object.
* In a second transaction, read the new object and traverse relationships to the existing object, and trigger
* an indirect relationship. The existing wrapped indirection query on the indirect relationship should
* ensure that the UnitOfWork (RepeatableWriteUnitOfWork) used for the query is unreferenced correctly, to
* avoid referencing it within the shared cache, via the existing referenced query.
*/
public void testTransparentIndirectionQuerySessionReset() {
Bill bill = null;
BillLine billLine = null;
BillLineItem billLineItem = null;
BillAction billAction = null;
// setup
EntityManager em = createEntityManager();
try {
beginTransaction(em);
bill = new Bill();
bill.setOrderIdentifier("Test Bill");
billLine = new BillLine();
billLine.setQuantity(6);
bill.addBillLine(billLine);
billLineItem = new BillLineItem();
billLineItem.setItemName("Test Widget");
billLine.addBillLineItem(billLineItem);
em.persist(bill);
em.persist(billLine);
em.persist(billLineItem);
commitTransaction(em);
assertNotNull("bill should be non-null", bill);
assertNotNull("bill's id should be non-null", bill.getId());
assertNotNull("billLine should be non-null", billLine);
assertNotNull("billLine's id should be non-null", billLine.getId());
assertNotNull("billLineItem should be non-null", billLineItem);
assertNotNull("billLineItem's id should be non-null", billLineItem.getId());
} finally {
closeEntityManager(em);
// start test with an empty cache
clearCache();
}
try {
// test - txn #1 : read, modify, persist, refresh related Entity
em = createEntityManager();
try {
beginTransaction(em);
Bill billReRead = em.createQuery("SELECT b FROM Bill b where b.id=" + bill.getId(), Bill.class).getSingleResult();
assertNotNull(billReRead);
BillLine billLineReRead = billReRead.getBillLines().get(0);
assertNotNull(billLineReRead);
billAction = new BillAction();
billAction.setBillLine(billLineReRead);
billAction.setPriority(2);
em.persist(billAction);
// refresh
em.refresh(billLineReRead);
commitTransaction(em);
} finally {
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
closeEntityManager(em);
}
// test - txn #2 : read, modify and trigger relationship on related Entity
em = createEntityManager();
try {
beginTransaction(em);
Bill billReRead = em.createQuery("SELECT b FROM Bill b where b.id=" + bill.getId(), Bill.class).getSingleResult();
// DM: if there is no update to Order, issue doesn't occur
billReRead.setStatus(Bill.STATUS_PROCESSING);
BillAction billActionReRead = em.createQuery("SELECT a FROM BillAction a where a.id=" + billAction.getId(), BillAction.class).getSingleResult();
assertNotNull(billActionReRead);
BillLine billLineReRead = billActionReRead.getBillLine();
assertNotNull(billLineReRead);
// Access & trigger BillLine -> BillLineItems list
billLineReRead.getBillLineItems().size();
commitTransaction(em);
} finally {
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
closeEntityManager(em);
}
// verify
// Failure case: non-null session (a UnitOfWork/RepeatableWriteUnitOfWork) referenced in the wrapped ValueHolder's query.
ServerSession srv = getServerSession();
ClassDescriptor descriptor = srv.getDescriptor(billLine);
Long blId = billLine.getId();
BillLine cachedBillLine = (BillLine) srv.getIdentityMapAccessor().getFromIdentityMap(blId, BillLine.class);
assertNotNull("BillLine from shared cache is null with id: " + blId, cachedBillLine);
OneToManyMapping mapping = (OneToManyMapping) srv.getDescriptor(cachedBillLine).getMappingForAttributeName("billLineItems");
IndirectContainer billLineItemsVH = (IndirectContainer) mapping.getAttributeValueFromObject(cachedBillLine);
assertNotNull("BillLineItems ValueHolder should not be null", billLineItemsVH);
ValueHolderInterface wrappedVH = billLineItemsVH.getValueHolder();
assertNotNull("Wrapped ValueHolder should not be null", wrappedVH);
if (wrappedVH instanceof QueryBasedValueHolder) {
DatabaseQuery query = ((QueryBasedValueHolder) wrappedVH).getQuery();
if (query.getSession() != null && query.getSession().isUnitOfWork()) {
fail("UnitOfWork referenced in Query from wrapped QueryBasedValueHolder in shared cache");
}
}
} finally {
// reset
em = createEntityManager();
try {
beginTransaction(em);
bill = em.find(Bill.class, bill.getId());
if (bill != null) {
em.remove(bill);
}
billLine = em.find(BillLine.class, billLine.getId());
if (billLine != null) {
em.remove(billLine);
}
billLineItem = em.find(BillLineItem.class, billLineItem.getId());
if (billLineItem != null) {
em.remove(billLineItem);
}
if (billAction != null) {
billAction = em.find(BillAction.class, billAction.getId());
if (billAction != null) {
em.remove(billAction);
}
}
commitTransaction(em);
} finally {
closeEntityManager(em);
}
}
}
Aggregations