use of org.eclipse.persistence.queries.DeleteObjectQuery in project eclipselink by eclipse-ee4j.
the class AggregateCollectionMapping method preDelete.
/**
* INTERNAL:
* Delete privately owned parts
*/
@Override
public void preDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException {
if (isReadOnly()) {
return;
}
AbstractSession session = query.getSession();
// If privately owned parts have their privately own parts, delete those one by one
// else delete everything in one shot.
int index = 0;
if (mustDeleteReferenceObjectsOneByOne()) {
Object objects = getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession());
ContainerPolicy cp = getContainerPolicy();
if (this.isCascadeOnDeleteSetOnDatabase && session.isUnitOfWork()) {
for (Object iterator = cp.iteratorFor(objects); cp.hasNext(iterator); ) {
Object wrappedObject = cp.nextEntry(iterator, session);
Object object = cp.unwrapIteratorResult(wrappedObject);
((UnitOfWorkImpl) session).getCascadeDeleteObjects().add(object);
}
}
for (Object iter = cp.iteratorFor(objects); cp.hasNext(iter); ) {
Object wrappedObject = cp.nextEntry(iter, session);
DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
deleteQuery.setIsExecutionClone(true);
Map extraData = null;
if (this.listOrderField != null) {
extraData = new DatabaseRecord(1);
extraData.put(this.listOrderField, index++);
}
prepareModifyQueryForDelete(query, deleteQuery, wrappedObject, extraData);
session.executeQuery(deleteQuery, deleteQuery.getTranslationRow());
cp.propogatePreDelete(query, wrappedObject);
}
if (!session.isUnitOfWork()) {
// This deletes any objects on the database, as the collection in memory may has been changed.
// This is not required for unit of work, as the update would have already deleted these objects,
// and the backup copy will include the same objects causing double deletes.
verifyDeleteForUpdate(query);
}
} else {
deleteAll(query, session);
}
}
use of org.eclipse.persistence.queries.DeleteObjectQuery in project eclipselink by eclipse-ee4j.
the class ExpressionQueryMechanism method buildDeleteStatement.
/**
* Return the appropriate delete statement
*/
protected SQLDeleteStatement buildDeleteStatement(DatabaseTable table) {
SQLDeleteStatement deleteStatement = new SQLDeleteStatement();
Expression whereClause;
whereClause = getDescriptor().getObjectBuilder().buildDeleteExpression(table, getTranslationRow(), ((DeleteObjectQuery) getQuery()).usesOptimisticLocking());
deleteStatement.setWhereClause(whereClause);
deleteStatement.setTable(table);
deleteStatement.setTranslationRow(getTranslationRow());
deleteStatement.setHintString(getQuery().getHintString());
return deleteStatement;
}
use of org.eclipse.persistence.queries.DeleteObjectQuery in project eclipselink by eclipse-ee4j.
the class DirectCollectionMapping method postUpdateWithChangeSetListOrder.
/**
* INTERNAL:
* Update private owned part.
*/
protected void postUpdateWithChangeSetListOrder(WriteObjectQuery writeQuery) throws DatabaseException {
ObjectChangeSet changeSet = writeQuery.getObjectChangeSet();
DirectCollectionChangeRecord changeRecord = (DirectCollectionChangeRecord) changeSet.getChangesForAttributeNamed(this.getAttributeName());
if (changeRecord == null) {
return;
}
for (int index = 0; index < getReferenceKeyFields().size(); index++) {
DatabaseField referenceKey = getReferenceKeyFields().get(index);
DatabaseField sourceKey = getSourceKeyFields().get(index);
Object sourceKeyValue = writeQuery.getTranslationRow().get(sourceKey);
writeQuery.getTranslationRow().put(referenceKey, sourceKeyValue);
}
boolean shouldRepairOrder = false;
if (changeRecord.getLatestCollection() instanceof IndirectList) {
shouldRepairOrder = ((IndirectList) changeRecord.getLatestCollection()).isListOrderBrokenInDb();
}
if (shouldRepairOrder) {
// delete all members of collection
DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
deleteQuery.setObject(writeQuery.getObject());
deleteQuery.setSession(writeQuery.getSession());
deleteQuery.setTranslationRow(writeQuery.getTranslationRow());
// Hey I might actually want to use an inner class here... ok array for now.
Object[] eventDeleteAll = new Object[2];
eventDeleteAll[0] = DeleteAll;
eventDeleteAll[1] = deleteQuery;
writeQuery.getSession().getCommitManager().addDataModificationEvent(this, eventDeleteAll);
// re-insert them back
for (int i = 0; i < ((List) changeRecord.getLatestCollection()).size(); i++) {
Object value = ((List) changeRecord.getLatestCollection()).get(i);
value = getFieldValue(value, writeQuery.getSession());
AbstractRecord insertRow = writeQuery.getTranslationRow().clone();
insertRow.add(getDirectField(), value);
insertRow.add(this.listOrderField, i);
// Hey I might actually want to use an inner class here... ok array for now.
Object[] event = new Object[3];
event[0] = Insert;
event[1] = getInsertQuery();
event[2] = insertRow;
writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
}
((IndirectList) changeRecord.getLatestCollection()).setIsListOrderBrokenInDb(false);
changeRecord.setOrderHasBeenRepaired(true);
return;
}
if (changeRecord.getChangedIndexes() == null) {
compareListsForChange((List) changeRecord.getOriginalCollection(), (List) changeRecord.getLatestCollection(), changeRecord, writeQuery.getSession());
}
Iterator<Map.Entry<Object, Set[]>> it = changeRecord.getChangedIndexes().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Object, Set[]> entry = it.next();
Object value = entry.getKey();
if (getValueConverter() != null) {
value = getValueConverter().convertObjectValueToDataValue(value, writeQuery.getSession());
}
Set[] indexes = entry.getValue();
Set indexesBefore = indexes[0];
Set indexesAfter = indexes[1];
if (indexesAfter == null) {
// All copies of the target object deleted - don't need to verify order field contents.
AbstractRecord deleteRow = writeQuery.getTranslationRow().clone();
// Hey I might actually want to use an inner class here... ok array for now.
Object[] event = new Object[3];
event[0] = Delete;
if (value == null) {
// Bug 306075 - for deleting a null value from a collection
event[1] = getDeleteNullQuery();
} else {
deleteRow.add(getDirectField(), value);
event[1] = getDeleteQuery();
}
event[2] = deleteRow;
writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
} else if (indexesAfter.isEmpty()) {
// Some copies of the target objects should be deleted, some left in the db
Iterator<Integer> itBefore = indexesBefore.iterator();
while (itBefore.hasNext()) {
AbstractRecord deleteAtIndexRow = writeQuery.getTranslationRow().clone();
deleteAtIndexRow.add(getDirectField(), value);
deleteAtIndexRow.add(this.listOrderField, itBefore.next());
// Hey I might actually want to use an inner class here... ok array for now.
Object[] event = new Object[3];
event[0] = DeleteAtIndex;
event[1] = deleteAtIndexQuery;
event[2] = deleteAtIndexRow;
writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
}
} else {
if (indexesBefore == null || indexesBefore.isEmpty()) {
// insert the object for each index in indexesAfter
Iterator<Integer> itAfter = indexesAfter.iterator();
while (itAfter.hasNext()) {
AbstractRecord insertRow = writeQuery.getTranslationRow().clone();
insertRow.add(getDirectField(), value);
insertRow.add(this.listOrderField, itAfter.next());
// Hey I might actually want to use an inner class here... ok array for now.
Object[] event = new Object[3];
event[0] = Insert;
event[1] = getInsertQuery();
event[2] = insertRow;
writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
}
} else {
Iterator<Integer> itBefore = indexesBefore.iterator();
Iterator<Integer> itAfter = indexesAfter.iterator();
while (itBefore.hasNext() || itAfter.hasNext()) {
if (itBefore.hasNext()) {
if (itAfter.hasNext()) {
// update the object changing index from indexBefore to indexAfter
AbstractRecord updateAtIndexRow = writeQuery.getTranslationRow().clone();
updateAtIndexRow.add(getDirectField(), value);
updateAtIndexRow.add(this.listOrderField, itBefore.next());
// Hey I might actually want to use an inner class here... ok array for now.
Object[] event = new Object[4];
event[0] = UpdateAtIndex;
event[1] = updateAtIndexQuery;
event[2] = updateAtIndexRow;
DatabaseRecord modifyRow = new DatabaseRecord(1);
modifyRow.add(this.listOrderField, itAfter.next());
event[3] = modifyRow;
writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
} else {
// delete the object at indexBefore
AbstractRecord deleteAtIndexRow = writeQuery.getTranslationRow().clone();
deleteAtIndexRow.add(getDirectField(), value);
deleteAtIndexRow.add(this.listOrderField, itBefore.next());
// Hey I might actually want to use an inner class here... ok array for now.
Object[] event = new Object[3];
event[0] = DeleteAtIndex;
event[1] = deleteAtIndexQuery;
event[2] = deleteAtIndexRow;
writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
}
} else {
// itAfter.hasNext() must be true
// insert the object at indexAfter
AbstractRecord insertRow = writeQuery.getTranslationRow().clone();
insertRow.add(getDirectField(), value);
insertRow.add(this.listOrderField, itAfter.next());
// Hey I might actually want to use an inner class here... ok array for now.
Object[] event = new Object[3];
event[0] = Insert;
event[1] = getInsertQuery();
event[2] = insertRow;
writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
}
}
}
}
}
}
use of org.eclipse.persistence.queries.DeleteObjectQuery in project eclipselink by eclipse-ee4j.
the class ObjectReferenceMapping method preDelete.
/**
* INTERNAL:
* Delete privately owned parts
*/
@Override
public void preDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException {
// Deletion takes place according the the cascading policy
if (!shouldObjectModifyCascadeToParts(query)) {
return;
}
AbstractSession session = query.getSession();
// Get the privately owned parts.
Object objectInMemory = getRealAttributeValueFromObject(query.getObject(), session);
Object objectFromDatabase = null;
// Because the value in memory may have been changed we check the previous value or database value.
objectFromDatabase = readPrivateOwnedForObject(query);
// If the value was changed, both values must be deleted (uow will have inserted the new one).
if ((objectFromDatabase != null) && (objectFromDatabase != objectInMemory)) {
// Also check pk as may not be maintaining identity.
Object keyForObjectInMemory = null;
Object keyForObjectInDatabase = getPrimaryKeyForObject(objectFromDatabase, session);
if (objectInMemory != null) {
keyForObjectInMemory = getPrimaryKeyForObject(objectInMemory, session);
}
if ((keyForObjectInMemory == null) || !keyForObjectInDatabase.equals(keyForObjectInMemory)) {
if (this.isCascadeOnDeleteSetOnDatabase && !hasRelationTableMechanism() && session.isUnitOfWork()) {
((UnitOfWorkImpl) session).getCascadeDeleteObjects().add(objectFromDatabase);
}
DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
deleteQuery.setIsExecutionClone(true);
deleteQuery.setObject(objectFromDatabase);
deleteQuery.setCascadePolicy(query.getCascadePolicy());
session.executeQuery(deleteQuery);
}
}
if (!isForeignKeyRelationship()) {
if (objectInMemory != null) {
if (this.isCascadeOnDeleteSetOnDatabase && !hasRelationTableMechanism() && session.isUnitOfWork()) {
((UnitOfWorkImpl) session).getCascadeDeleteObjects().add(objectInMemory);
}
// PERF: Avoid query execution if already deleted.
if (session.getCommitManager().isCommitCompletedInPostOrIgnore(objectInMemory)) {
return;
}
DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
deleteQuery.setIsExecutionClone(true);
deleteQuery.setObject(objectInMemory);
deleteQuery.setCascadePolicy(query.getCascadePolicy());
session.executeQuery(deleteQuery);
}
} else {
// The actual deletion of part takes place in postDeleteForObjectUsing(...).
if (objectInMemory != null) {
query.setProperty(this, objectInMemory);
}
}
}
use of org.eclipse.persistence.queries.DeleteObjectQuery in project eclipselink by eclipse-ee4j.
the class StoredProcedureGenerator method generateDeleteStoredProcedure.
/**
* INTERNAL: Generates the delete stored procedure for this descriptor
*/
protected StoredProcedureDefinition generateDeleteStoredProcedure(ClassDescriptor descriptor) {
DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
deleteQuery.setDescriptor(descriptor);
deleteQuery.setModifyRow(new DatabaseRecord());
return this.generateObjectStoredProcedure(deleteQuery, descriptor.getPrimaryKeyFields(), "DEL_");
}
Aggregations