use of org.eclipse.persistence.internal.sessions.UnitOfWorkImpl in project eclipselink by eclipse-ee4j.
the class EntityManagerJUnitTestSuite method testDetachRemovedObject.
// detach(object) on a removed object does not throw exception. This test only
// checks whether an removed object is completely deleted from the
// getDeletedObject()Map after 'detach(removedobject)' is invoked
public void testDetachRemovedObject() {
// create an Employee
Employee emp = new Employee();
emp.setFirstName("testDetachRemovedObjectEmployee");
// persist the Employee
EntityManager em = createEntityManager();
try {
beginTransaction(em);
em.persist(emp);
commitTransaction(em);
} catch (RuntimeException re) {
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
throw re;
}
beginTransaction(em);
// attempt to remove the Employee
em.remove(em.find(Employee.class, emp.getId()));
commitTransaction(em);
beginTransaction(em);
EntityManagerImpl em1 = (EntityManagerImpl) em.getDelegate();
try {
// attempt to detach the Employee
em.detach(emp);
UnitOfWork uow = em1.getUnitOfWork();
UnitOfWorkImpl uowImpl = (UnitOfWorkImpl) uow;
boolean afterClear = uowImpl.getDeletedObjects().containsKey(emp);
assertFalse("exception thrown when detaching a removed entity is attempted.", afterClear);
} catch (IllegalArgumentException iae) {
return;
} finally {
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
use of org.eclipse.persistence.internal.sessions.UnitOfWorkImpl in project eclipselink by eclipse-ee4j.
the class BatchValueHolder method instantiateForUnitOfWorkValueHolder.
/**
* Triggers UnitOfWork valueholders directly without triggering the wrapped
* valueholder (this).
* <p>
* When in transaction and/or for pessimistic locking the
* UnitOfWorkValueHolder needs to be triggered directly without triggering
* the wrapped valueholder. However only the wrapped valueholder knows how
* to trigger the indirection, i.e. it may be a batchValueHolder, and it
* stores all the info like the row and the query. Note: This method is not
* thread-safe. It must be used in a synchronized manner.
* The batch value holder must use a batch query relative to the unit of work,
* as the batch is local to the unit of work.
*/
@Override
@SuppressWarnings({ "unchecked" })
public T instantiateForUnitOfWorkValueHolder(UnitOfWorkValueHolder<T> unitOfWorkValueHolder) {
UnitOfWorkImpl unitOfWork = unitOfWorkValueHolder.getUnitOfWork();
ReadQuery localQuery = unitOfWork.getBatchQueries().get(this.query);
if (localQuery == null) {
localQuery = (ReadQuery) this.query.clone();
unitOfWork.getBatchQueries().put(this.query, localQuery);
}
return (T) this.mapping.extractResultFromBatchQuery(localQuery, this.parentCacheKey, this.row, unitOfWorkValueHolder.getUnitOfWork(), this.originalQuery);
}
use of org.eclipse.persistence.internal.sessions.UnitOfWorkImpl in project eclipselink by eclipse-ee4j.
the class IdentityMapManager method getFromIdentityMap.
public Object getFromIdentityMap(Expression selectionCriteria, Class<?> theClass, DataRecord translationRow, int valueHolderPolicy, boolean conforming, boolean shouldReturnInvalidatedObjects, ClassDescriptor descriptor) {
UnitOfWorkImpl unitOfWork = (conforming) ? (UnitOfWorkImpl) this.session : null;
this.session.startOperationProfile(SessionProfiler.Caching);
try {
if (selectionCriteria != null) {
// PERF: Avoid clone of expression.
ExpressionBuilder builder = selectionCriteria.getBuilder();
if (builder.getSession() == null) {
builder.setSession(this.session.getRootSession(null));
builder.setQueryClass(theClass);
}
}
IdentityMap map = getIdentityMap(descriptor, false);
// Bug #321041 - if policy is set to trigger indirection, then iterate over a copy of the cache keys collection
// to avoid a ConcurrentModificationException
Enumeration<CacheKey> cacheEnum = valueHolderPolicy == InMemoryQueryIndirectionPolicy.SHOULD_TRIGGER_INDIRECTION ? map.cloneKeys() : map.keys();
// cache the current time to avoid calculating it every time through the loop
long currentTimeInMillis = System.currentTimeMillis();
while (cacheEnum.hasMoreElements()) {
CacheKey key = cacheEnum.nextElement();
if (!shouldReturnInvalidatedObjects && descriptor.getCacheInvalidationPolicy().isInvalidated(key, currentTimeInMillis)) {
continue;
}
Object object = key.getObject();
// Bug # 3216337 - key.getObject() should check for null; object may be GC'd (MWN)
if (object == null) {
continue;
}
// Must check for inheritance.
if ((object.getClass() == theClass) || (theClass.isInstance(object))) {
if (selectionCriteria == null) {
// bug 2782991: if first found was deleted nothing returned.
if (!(conforming && unitOfWork.isObjectDeleted(object))) {
return object;
}
}
// CR 3677 integration of a ValueHolderPolicy
try {
if (selectionCriteria.doesConform(object, this.session, (AbstractRecord) translationRow, valueHolderPolicy)) {
// bug 2782991: if first found was deleted nothing returned.
if (!(conforming && unitOfWork.isObjectDeleted(object))) {
return object;
}
}
} catch (QueryException queryException) {
if (queryException.getErrorCode() == QueryException.MUST_INSTANTIATE_VALUEHOLDERS) {
if (valueHolderPolicy == InMemoryQueryIndirectionPolicy.SHOULD_IGNORE_EXCEPTION_RETURN_CONFORMED) {
// bug 2782991: if first found was deleted nothing returned.
if (!(conforming && unitOfWork.isObjectDeleted(object))) {
return object;
}
} else if (valueHolderPolicy == InMemoryQueryIndirectionPolicy.SHOULD_IGNORE_EXCEPTION_RETURN_NOT_CONFORMED) {
// For bug 2667870 just skip this item, but do not abort.
} else {
throw queryException;
}
} else {
throw queryException;
}
}
}
}
} finally {
this.session.endOperationProfile(SessionProfiler.Caching);
}
return null;
}
use of org.eclipse.persistence.internal.sessions.UnitOfWorkImpl in project eclipselink by eclipse-ee4j.
the class AggregateCollectionMapping method buildCloneForPartObject.
/**
* INTERNAL:
* Require for cloning, the part must be cloned.
* Ignore the objects, use the attribute value.
* this is identical to the super class except that the element must be added to the new
* aggregates collection so that the referenced objects will be cloned correctly
*/
@Override
public Object buildCloneForPartObject(Object attributeValue, Object original, CacheKey cacheKey, Object clone, AbstractSession cloningSession, Integer refreshCascade, boolean isExisting, boolean isFromSharedCache) {
ContainerPolicy containerPolicy = getContainerPolicy();
if (attributeValue == null) {
return containerPolicy.containerInstance(1);
}
Object clonedAttributeValue = containerPolicy.containerInstance(containerPolicy.sizeFor(attributeValue));
Object temporaryCollection = null;
if (isSynchronizeOnMerge) {
// I will use a temporary collection to help speed up the process
synchronized (attributeValue) {
temporaryCollection = containerPolicy.cloneFor(attributeValue);
}
} else {
temporaryCollection = attributeValue;
}
for (Object valuesIterator = containerPolicy.iteratorFor(temporaryCollection); containerPolicy.hasNext(valuesIterator); ) {
Object wrappedElement = containerPolicy.nextEntry(valuesIterator, cloningSession);
Object originalElement = containerPolicy.unwrapIteratorResult(wrappedElement);
// need to add to aggregate list in the case that there are related objects.
if (cloningSession.isUnitOfWork() && ((UnitOfWorkImpl) cloningSession).isOriginalNewObject(original)) {
((UnitOfWorkImpl) cloningSession).addNewAggregate(originalElement);
}
Object cloneValue = buildElementClone(originalElement, clone, cacheKey, refreshCascade, cloningSession, isExisting, isFromSharedCache);
Object clonedKey = containerPolicy.buildCloneForKey(containerPolicy.keyFromIterator(valuesIterator), clone, cacheKey, refreshCascade, cloningSession, isExisting, isFromSharedCache);
containerPolicy.addInto(clonedKey, cloneValue, clonedAttributeValue, cloningSession);
}
if (temporaryCollection instanceof IndirectList) {
((IndirectList) clonedAttributeValue).setIsListOrderBrokenInDb(((IndirectList) temporaryCollection).isListOrderBrokenInDb());
}
return clonedAttributeValue;
}
use of org.eclipse.persistence.internal.sessions.UnitOfWorkImpl in project eclipselink by eclipse-ee4j.
the class ReadAllQuery method executeObjectLevelReadQuery.
/**
* INTERNAL:
* Execute the query.
* Get the rows and build the object from the rows.
* @exception DatabaseException - an error has occurred on the database
* @return java.lang.Object collection of objects resulting from execution of query.
*/
@Override
protected Object executeObjectLevelReadQuery() throws DatabaseException {
Object result = null;
if (this.containerPolicy.overridesRead()) {
this.executionTime = System.currentTimeMillis();
return this.containerPolicy.execute();
}
if (this.descriptor.isDescriptorForInterface()) {
Object returnValue = this.descriptor.getInterfacePolicy().selectAllObjectsUsingMultipleTableSubclassRead(this);
this.executionTime = System.currentTimeMillis();
return returnValue;
}
if (this.descriptor.hasTablePerClassPolicy() && this.descriptor.isAbstract()) {
result = this.containerPolicy.containerInstance();
if (this.shouldIncludeData) {
ComplexQueryResult complexResult = new ComplexQueryResult();
complexResult.setResult(result);
complexResult.setData(new ArrayList());
result = complexResult;
}
} else {
Object sopObject = getTranslationRow().getSopObject();
boolean useOptimization = false;
if (sopObject == null) {
useOptimization = usesResultSetAccessOptimization();
}
if (useOptimization) {
DatabaseCall call = ((DatasourceCallQueryMechanism) this.queryMechanism).selectResultSet();
this.executionTime = System.currentTimeMillis();
Statement statement = call.getStatement();
ResultSet resultSet = call.getResult();
DatabaseAccessor dbAccessor = (DatabaseAccessor) getAccessor();
boolean exceptionOccured = false;
try {
if (this.session.isUnitOfWork()) {
result = registerResultSetInUnitOfWork(resultSet, call.getFields(), call.getFieldsArray(), (UnitOfWorkImpl) this.session, this.translationRow);
} else {
result = this.containerPolicy.containerInstance();
this.descriptor.getObjectBuilder().buildObjectsFromResultSetInto(this, resultSet, call.getFields(), call.getFieldsArray(), result);
}
} catch (SQLException exception) {
exceptionOccured = true;
DatabaseException commException = dbAccessor.processExceptionForCommError(this.session, exception, call);
if (commException != null) {
throw commException;
}
throw DatabaseException.sqlException(exception, call, dbAccessor, this.session, false);
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
if (dbAccessor != null) {
if (statement != null) {
dbAccessor.releaseStatement(statement, call.getSQLString(), call, this.session);
}
}
if (call.hasAllocatedConnection()) {
getExecutionSession().releaseConnectionAfterCall(this);
}
} catch (RuntimeException cleanupException) {
if (!exceptionOccured) {
throw cleanupException;
}
} catch (SQLException cleanupSQLException) {
if (!exceptionOccured) {
throw DatabaseException.sqlException(cleanupSQLException, call, dbAccessor, this.session, false);
}
}
}
} else {
List<AbstractRecord> rows;
if (sopObject != null) {
Object valuesIterator = this.containerPolicy.iteratorFor(getTranslationRow().getSopObject());
int size = this.containerPolicy.sizeFor(sopObject);
rows = new ArrayList<>(size);
while (this.containerPolicy.hasNext(valuesIterator)) {
Object memberSopObject = this.containerPolicy.next(valuesIterator, this.session);
DatabaseRecord memberRow = new DatabaseRecord(0);
memberRow.setSopObject(memberSopObject);
rows.add(memberRow);
}
this.executionTime = System.currentTimeMillis();
} else {
rows = getQueryMechanism().selectAllRows();
this.executionTime = System.currentTimeMillis();
// If using 1-m joins, must set all rows.
if (hasJoining() && this.joinedAttributeManager.isToManyJoin()) {
this.joinedAttributeManager.setDataResults(rows, this.session);
}
// Batch fetching in IN requires access to the rows to build the id array.
if ((this.batchFetchPolicy != null) && this.batchFetchPolicy.isIN()) {
this.batchFetchPolicy.setDataResults(rows);
}
}
if (this.session.isUnitOfWork()) {
//
result = registerResultInUnitOfWork(rows, (UnitOfWorkImpl) this.session, this.translationRow, true);
} else {
if (rows instanceof ThreadCursoredList) {
result = this.containerPolicy.containerInstance();
} else {
result = this.containerPolicy.containerInstance(rows.size());
}
this.descriptor.getObjectBuilder().buildObjectsInto(this, rows, result);
}
if (sopObject != null) {
if (!this.descriptor.getObjectBuilder().isSimple()) {
// remove sopObject so it's not stuck in any value holder.
for (AbstractRecord row : rows) {
row.setSopObject(null);
}
}
} else {
if (this.shouldIncludeData) {
ComplexQueryResult complexResult = new ComplexQueryResult();
complexResult.setResult(result);
complexResult.setData(rows);
result = complexResult;
}
}
}
}
// Add the other (already registered) results and return them.
if (this.descriptor.hasTablePerClassPolicy()) {
result = this.containerPolicy.concatenateContainers(result, this.descriptor.getTablePerClassPolicy().selectAllObjectsUsingMultipleTableSubclassRead(this), this.session);
}
// If the results were empty, then ensure they get cached still.
if (shouldCacheQueryResults() && this.containerPolicy.isEmpty(result)) {
this.temporaryCachedQueryResults = InvalidObject.instance();
}
return result;
}
Aggregations