Search in sources :

Example 1 with BillLineItem

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);
        }
    }
}
Also used : ServerSession(org.eclipse.persistence.sessions.server.ServerSession) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) DatabaseQuery(org.eclipse.persistence.queries.DatabaseQuery) BillLine(org.eclipse.persistence.testing.models.jpa.advanced.BillLine) UnidirectionalOneToManyMapping(org.eclipse.persistence.mappings.UnidirectionalOneToManyMapping) OneToManyMapping(org.eclipse.persistence.mappings.OneToManyMapping) BillAction(org.eclipse.persistence.testing.models.jpa.advanced.BillAction) BillLineItem(org.eclipse.persistence.testing.models.jpa.advanced.BillLineItem) QueryBasedValueHolder(org.eclipse.persistence.internal.indirection.QueryBasedValueHolder) EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) ValueHolderInterface(org.eclipse.persistence.indirection.ValueHolderInterface) IndirectContainer(org.eclipse.persistence.indirection.IndirectContainer) Bill(org.eclipse.persistence.testing.models.jpa.advanced.Bill)

Aggregations

EntityManager (jakarta.persistence.EntityManager)1 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)1 IndirectContainer (org.eclipse.persistence.indirection.IndirectContainer)1 ValueHolderInterface (org.eclipse.persistence.indirection.ValueHolderInterface)1 QueryBasedValueHolder (org.eclipse.persistence.internal.indirection.QueryBasedValueHolder)1 JpaEntityManager (org.eclipse.persistence.jpa.JpaEntityManager)1 OneToManyMapping (org.eclipse.persistence.mappings.OneToManyMapping)1 UnidirectionalOneToManyMapping (org.eclipse.persistence.mappings.UnidirectionalOneToManyMapping)1 DatabaseQuery (org.eclipse.persistence.queries.DatabaseQuery)1 ServerSession (org.eclipse.persistence.sessions.server.ServerSession)1 Bill (org.eclipse.persistence.testing.models.jpa.advanced.Bill)1 BillAction (org.eclipse.persistence.testing.models.jpa.advanced.BillAction)1 BillLine (org.eclipse.persistence.testing.models.jpa.advanced.BillLine)1 BillLineItem (org.eclipse.persistence.testing.models.jpa.advanced.BillLineItem)1