Search in sources :

Example 16 with IndirectContainer

use of org.eclipse.persistence.indirection.IndirectContainer in project eclipselink by eclipse-ee4j.

the class ContainerIndirectionPolicy method buildContainer.

/**
 * Build a container with the initialized constructor.
 */
protected IndirectContainer buildContainer(final ValueHolderInterface<?> valueHolder) {
    try {
        IndirectContainer container = null;
        if (getContainerConstructor().getParameterTypes().length == 0) {
            container = PrivilegedAccessHelper.callDoPrivilegedWithException(() -> (IndirectContainer) PrivilegedAccessHelper.invokeConstructor(getContainerConstructor(), new Object[0]));
            container.setValueHolder(valueHolder);
        } else {
            container = PrivilegedAccessHelper.callDoPrivilegedWithException(() -> (IndirectContainer) PrivilegedAccessHelper.invokeConstructor(getContainerConstructor(), new Object[] { valueHolder }));
        }
        return container;
    } catch (Exception exception) {
        throw DescriptorException.invalidIndirectionPolicyOperation(this, "buildContainer constructor (" + getContainerConstructor() + ") Failed: " + exception);
    }
}
Also used : IndirectContainer(org.eclipse.persistence.indirection.IndirectContainer) DescriptorException(org.eclipse.persistence.exceptions.DescriptorException)

Example 17 with IndirectContainer

use of org.eclipse.persistence.indirection.IndirectContainer in project eclipselink by eclipse-ee4j.

the class ContainerIndirectionPolicy method cloneAttribute.

/**
 * INTERNAL:
 *    Return a clone of the attribute.
 *  @param buildDirectlyFromRow indicates that we are building the clone directly
 *  from a row as opposed to building the original from the row, putting it in
 *  the shared cache, and then cloning the original.
 */
@Override
public Object cloneAttribute(Object attributeValue, Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession, boolean buildDirectlyFromRow) {
    IndirectContainer container = (IndirectContainer) attributeValue;
    ValueHolderInterface<?> valueHolder = container.getValueHolder();
    ValueHolderInterface<?> newValueHolder = (ValueHolderInterface<?>) super.cloneAttribute(valueHolder, original, cacheKey, clone, refreshCascade, cloningSession, buildDirectlyFromRow);
    return buildContainer(newValueHolder);
}
Also used : ValueHolderInterface(org.eclipse.persistence.indirection.ValueHolderInterface) IndirectContainer(org.eclipse.persistence.indirection.IndirectContainer)

Example 18 with IndirectContainer

use of org.eclipse.persistence.indirection.IndirectContainer in project eclipselink by eclipse-ee4j.

the class FetchGroupAssert method assertNotFetchedAttribute.

/**
 * Verify that the attribute path is loaded.
 */
public static void assertNotFetchedAttribute(EntityManagerFactory emf, Object entity, String... attribute) {
    assertNotNull("EntityManagerFactory is null", emf);
    assertNotNull("Entity is null", entity);
    Server session = ((org.eclipse.persistence.jpa.JpaEntityManager) emf.createEntityManager()).getServerSession();
    assertNotNull("No Server session found for: " + emf, session);
    ClassDescriptor desc = session.getClassDescriptor(entity);
    assertNotNull("No descriptor found for: " + entity, desc);
    Object value = entity;
    for (int index = 0; index < attribute.length - 1; index++) {
        String attrName = attribute[index];
        if (desc.hasFetchGroupManager()) {
            assertTrue("Attribute: '" + attrName + "' not fetched on: " + value, desc.getFetchGroupManager().isAttributeFetched(value, attrName));
        }
        DatabaseMapping mapping = desc.getMappingForAttributeName(attrName);
        value = mapping.getAttributeValueFromObject(value);
        if (value instanceof IndirectContainer) {
            value = ((IndirectContainer) value).getValueHolder();
        }
        if (value instanceof ValueHolderInterface) {
            ValueHolderInterface vhi = (ValueHolderInterface) value;
            assertTrue("ValueHolder for: '" + attrName + "' not instantiated", vhi.isInstantiated());
            value = vhi.getValue();
        }
    }
}
Also used : Server(org.eclipse.persistence.sessions.server.Server) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) ValueHolderInterface(org.eclipse.persistence.indirection.ValueHolderInterface) IndirectContainer(org.eclipse.persistence.indirection.IndirectContainer) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping)

Example 19 with IndirectContainer

use of org.eclipse.persistence.indirection.IndirectContainer in project eclipselink by eclipse-ee4j.

the class FetchGroupAssert method assertFetchedAttribute.

/**
 * Verify that the attribute path specified is loaded in the provided entity
 */
public static void assertFetchedAttribute(EntityManagerFactory emf, Object entity, String... attribute) {
    assertNotNull("EntityManagerFactory is null", emf);
    assertNotNull("Entity is null", entity);
    Server session = ((org.eclipse.persistence.jpa.JpaEntityManager) emf.createEntityManager()).getServerSession();
    assertNotNull("No Server session found for: " + emf, session);
    ClassDescriptor desc = session.getClassDescriptor(entity);
    assertNotNull("No descriptor found for: " + entity, desc);
    Object value = entity;
    if (attribute.length > 1) {
        String attrName = attribute[1];
        if (desc.hasFetchGroupManager()) {
            assertTrue("Attribute: '" + attrName + "' not fetched on: " + value, desc.getFetchGroupManager().isAttributeFetched(value, attrName));
        }
        DatabaseMapping mapping = desc.getMappingForAttributeName(attrName);
        value = mapping.getAttributeValueFromObject(value);
        if (value instanceof IndirectContainer) {
            value = ((IndirectContainer) value).getValueHolder();
        }
        if (value instanceof ValueHolderInterface) {
            ValueHolderInterface vhi = (ValueHolderInterface) value;
            assertTrue("ValueHolder for: '" + attrName + "' not instantiated", vhi.isInstantiated());
            value = vhi.getValue();
        }
        String[] tail = new String[attribute.length - 1];
        System.arraycopy(attribute, 1, tail, 0, attribute.length - 1);
        if (value instanceof Collection<?>) {
            for (Object obj : ((Collection<?>) value)) {
                assertFetchedAttribute(emf, value, tail);
            }
        } else {
            assertFetchedAttribute(emf, value, tail);
        }
    } else {
        // This is where the actual end attribute in the path is validated.
        if (desc.hasFetchGroupManager()) {
            assertTrue(desc.getFetchGroupManager().isAttributeFetched(value, attribute[0]));
        }
    }
}
Also used : Server(org.eclipse.persistence.sessions.server.Server) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) ValueHolderInterface(org.eclipse.persistence.indirection.ValueHolderInterface) IndirectContainer(org.eclipse.persistence.indirection.IndirectContainer) Collection(java.util.Collection) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping)

Example 20 with IndirectContainer

use of org.eclipse.persistence.indirection.IndirectContainer 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

IndirectContainer (org.eclipse.persistence.indirection.IndirectContainer)20 AbstractOrder (org.eclipse.persistence.testing.models.transparentindirection.AbstractOrder)9 ValueHolderInterface (org.eclipse.persistence.indirection.ValueHolderInterface)5 AbstractOrderLine (org.eclipse.persistence.testing.models.transparentindirection.AbstractOrderLine)4 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)3 ExpressionBuilder (org.eclipse.persistence.expressions.ExpressionBuilder)2 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)2 UnitOfWork (org.eclipse.persistence.sessions.UnitOfWork)2 Server (org.eclipse.persistence.sessions.server.Server)2 FieldOffice (org.eclipse.persistence.testing.models.relationshipmaintenance.FieldOffice)2 SalesPerson (org.eclipse.persistence.testing.models.relationshipmaintenance.SalesPerson)2 AbstractSalesRep (org.eclipse.persistence.testing.models.transparentindirection.AbstractSalesRep)2 EntityManager (jakarta.persistence.EntityManager)1 Collection (java.util.Collection)1 DescriptorException (org.eclipse.persistence.exceptions.DescriptorException)1 QueryBasedValueHolder (org.eclipse.persistence.internal.indirection.QueryBasedValueHolder)1 RemoteSessionController (org.eclipse.persistence.internal.sessions.remote.RemoteSessionController)1 RemoteUnitOfWork (org.eclipse.persistence.internal.sessions.remote.RemoteUnitOfWork)1 JpaEntityManager (org.eclipse.persistence.jpa.JpaEntityManager)1 OneToManyMapping (org.eclipse.persistence.mappings.OneToManyMapping)1