/** * INTERNAL: Return the value of the field from the row or a value holder on the query to obtain * the object. Check for batch + aggregation reading. */ public Object valueFromRow( AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery query, AbstractSession executionSession) throws DatabaseException { Ref ref = (Ref) row.get(getField()); if (ref == null) { return null; } Struct struct; try { ((DatabaseAccessor) executionSession.getAccessor()).incrementCallCount(executionSession); java.sql.Connection connection = ((DatabaseAccessor) executionSession.getAccessor()).getConnection(); struct = (Struct) executionSession.getPlatform().getRefValue(ref, executionSession, connection); } catch (java.sql.SQLException exception) { throw DatabaseException.sqlException(exception, executionSession, false); } AbstractRecord targetRow = ((ObjectRelationalDataTypeDescriptor) getReferenceDescriptor()) .buildRowFromStructure(struct); ((DatabaseAccessor) executionSession.getAccessor()).decrementCallCount(); return getReferenceDescriptor().getObjectBuilder().buildObject(query, targetRow, joinManager); }
/** Delete all of the objects with the matching class. */ public void deleteAllObjects(Class theClass, List objects, AbstractSession session) { ClassDescriptor descriptor = null; if (((UnitOfWorkImpl) session).shouldOrderUpdates()) { // bug 331064 - Sort the delete order objects = sort(theClass, objects); } int size = objects.size(); for (int index = 0; index < size; index++) { Object objectToDelete = objects.get(index); if (objectToDelete.getClass() == theClass) { if (descriptor == null) { descriptor = session.getDescriptor(theClass); } // PERF: Get the descriptor query, to avoid extra query creation. DeleteObjectQuery deleteQuery = descriptor.getQueryManager().getDeleteQuery(); if (deleteQuery == null) { deleteQuery = new DeleteObjectQuery(); deleteQuery.setDescriptor(descriptor); } else { // Ensure original query has been prepared. deleteQuery.checkPrepare(session, deleteQuery.getTranslationRow()); deleteQuery = (DeleteObjectQuery) deleteQuery.clone(); } deleteQuery.setIsExecutionClone(true); deleteQuery.setObject(objectToDelete); session.executeQuery(deleteQuery); } } }
/** * delete all of the objects as a single transaction. This should delete the object in the correct * order to maintain referential integrity. */ public void deleteAllObjects(List objects) throws RuntimeException, DatabaseException, OptimisticLockException { this.isActive = true; AbstractSession session = getSession(); session.beginTransaction(); try { // PERF: Optimize single object case. if (objects.size() == 1) { deleteAllObjects(objects.get(0).getClass(), objects, session); } else { List commitOrder = getCommitOrder(); for (int orderIndex = commitOrder.size() - 1; orderIndex >= 0; orderIndex--) { Class theClass = (Class) commitOrder.get(orderIndex); deleteAllObjects(theClass, objects, session); } } session.commitTransaction(); } catch (RuntimeException exception) { try { session.rollbackTransaction(); } catch (Exception ignore) { } throw exception; } finally { reinitialize(); this.isActive = false; } }
/** * Commit all of the objects of the class type in the change set. This allows for the order of the * classes to be processed optimally. */ protected void commitNewObjectsForClassWithChangeSet( UnitOfWorkChangeSet uowChangeSet, Class theClass) { Map<ObjectChangeSet, ObjectChangeSet> newObjectChangesList = uowChangeSet.getNewObjectChangeSets().get(theClass); if (newObjectChangesList != null) { // may be no changes for that class type. AbstractSession session = getSession(); ClassDescriptor descriptor = session.getDescriptor(theClass); List<ObjectChangeSet> newChangeSets = new ArrayList(newObjectChangesList.values()); int size = newChangeSets.size(); for (int index = 0; index < size; index++) { ObjectChangeSet changeSetToWrite = newChangeSets.get(index); Object objectToWrite = changeSetToWrite.getUnitOfWorkClone(); if (!isProcessedCommit(objectToWrite)) { // PERF: Get the descriptor query, to avoid extra query creation. InsertObjectQuery commitQuery = descriptor.getQueryManager().getInsertQuery(); if (commitQuery == null) { commitQuery = new InsertObjectQuery(); commitQuery.setDescriptor(descriptor); } else { // Ensure original query has been prepared. commitQuery.checkPrepare(session, commitQuery.getTranslationRow()); commitQuery = (InsertObjectQuery) commitQuery.clone(); } commitQuery.setIsExecutionClone(true); commitQuery.setObjectChangeSet(changeSetToWrite); commitQuery.setObject(objectToWrite); commitQuery.cascadeOnlyDependentParts(); commitQuery.setModifyRow(null); session.executeQuery(commitQuery); } uowChangeSet.putNewObjectInChangesList(changeSetToWrite, session); } } }
/** * Commit changed of the objects of the class type in the change set. This allows for the order of * the classes to be processed optimally. */ protected void commitChangedObjectsForClassWithChangeSet( UnitOfWorkChangeSet uowChangeSet, Class theClass) { Map<ObjectChangeSet, ObjectChangeSet> objectChangesList = uowChangeSet.getObjectChanges().get(theClass); if (objectChangesList != null) { // may be no changes for that class type. ClassDescriptor descriptor = null; AbstractSession session = getSession(); Collection<ObjectChangeSet> changes = objectChangesList.values(); if (((UnitOfWorkImpl) session).shouldOrderUpdates()) { changes = new ArrayList(objectChangesList.values()); Collections.sort((List) changes); } for (ObjectChangeSet changeSetToWrite : changes) { Object objectToWrite = changeSetToWrite.getUnitOfWorkClone(); if (descriptor == null) { descriptor = session.getDescriptor(objectToWrite); } if (!isProcessedCommit(objectToWrite)) { // Commit and resume on failure can cause a new change set to be in existing, so need to // check here. WriteObjectQuery commitQuery = null; if (changeSetToWrite.isNew()) { commitQuery = new InsertObjectQuery(); } else { commitQuery = new UpdateObjectQuery(); } commitQuery.setIsExecutionClone(true); commitQuery.setDescriptor(descriptor); commitQuery.setObjectChangeSet(changeSetToWrite); commitQuery.setObject(objectToWrite); commitQuery.cascadeOnlyDependentParts(); // removed checking session type to set cascade level // will always be a unitOfWork so we need to cascade dependent parts session.executeQuery(commitQuery); } } } }
// bug 331064 - Sort the delete order based on PKs. private List sort(Class theClass, List objects) { ClassDescriptor descriptor = session.getDescriptor(theClass); org.eclipse.persistence.internal.descriptors.ObjectBuilder objectBuilder = descriptor.getObjectBuilder(); int size = objects.size(); TreeMap sortedObjects = new TreeMap(); for (int index = 0; index < size; index++) { Object objectToDelete = objects.get(index); if (objectToDelete.getClass() == theClass) { sortedObjects.put( objectBuilder.extractPrimaryKeyFromObject(objectToDelete, session), objectToDelete); } } return new ArrayList(sortedObjects.values()); }
/** INTERNAL: Initialize the mapping. */ public void initialize(AbstractSession session) throws DescriptorException { setReferenceDescriptor(session.getDescriptor(getReferenceClass())); if (referenceDescriptor == null) { throw DescriptorException.descriptorIsMissing(getReferenceClass().getName(), this); } // For bug 2730536 convert the field to be an ObjectRelationalDatabaseField. ObjectRelationalDatabaseField field = (ObjectRelationalDatabaseField) getField(); field.setSqlType(java.sql.Types.REF); if (referenceDescriptor instanceof ObjectRelationalDataTypeDescriptor) { field.setSqlTypeName( ((ObjectRelationalDataTypeDescriptor) referenceDescriptor).getStructureName()); } setField(getDescriptor().buildField(getField())); setFields(collectFields()); // Ref mapping requires native connection in WLS as the Ref is wrapped. getDescriptor().setIsNativeConnectionRequired(true); }