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);
}
}
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);
}
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();
}
}
}
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]));
}
}
}
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);
}
}
}
Aggregations