* This is used for both uow and non-uow (old-commit and change-set) operations.
*/
public void insertObjectForWrite() {
WriteObjectQuery writeQuery = getWriteObjectQuery();
ClassDescriptor descriptor = getDescriptor();
DescriptorQueryManager queryManager = descriptor.getQueryManager();
// check for user-defined query
if ((!writeQuery.isUserDefined())// this is not a user-defined query
&& queryManager.hasInsertQuery()// there is a user-defined query
&& isExpressionQueryMechanism()) {// this is not a hand-coded call (custom SQL etc.)
performUserDefinedInsert();
return;
}
Object object = writeQuery.getObject();
AbstractSession session = writeQuery.getSession();
ObjectChangeSet changeSet = writeQuery.getObjectChangeSet();
CommitManager commitManager = session.getCommitManager();
DescriptorEventManager eventManager = descriptor.getEventManager();
// This must be done after the custom query check, otherwise it will be done twice.
commitManager.markPreModifyCommitInProgress(object);
if (changeSet == null) {
// PERF: Avoid events if no listeners.
if (eventManager.hasAnyEventListeners()) {
// only throw the events if there is no changeset otherwise the event will be thrown twice
// once by the calculate changes code and here
eventManager.executeEvent(new DescriptorEvent(DescriptorEventManager.PreInsertEvent, writeQuery));
}
}
// check whether deep shallow modify is turned on
if (writeQuery.shouldCascadeParts()) {
queryManager.preInsert(writeQuery);
}
// In a unit of work/writeObjects the preInsert may have caused a shallow insert of this object,
// in this case this second write must do an update.
if (commitManager.isShallowCommitted(object)) {
updateForeignKeyFieldAfterInsert();
} else {
AbstractRecord modifyRow = writeQuery.getModifyRow();
if (modifyRow == null) {// Maybe have been passed in as in aggregate collection.
if (writeQuery.shouldCascadeParts()) {
writeQuery.setModifyRow(descriptor.getObjectBuilder().buildRow(object, session));
} else {
writeQuery.setModifyRow(descriptor.getObjectBuilder().buildRowForShallowInsert(object, session));
}
} else {
if (writeQuery.shouldCascadeParts()) {
writeQuery.setModifyRow(descriptor.getObjectBuilder().buildRow(modifyRow, object, session));
} else {
writeQuery.setModifyRow(descriptor.getObjectBuilder().buildRowForShallowInsert(modifyRow, object, session));
}
}
modifyRow = getModifyRow();
// the modify row and the translation row are the same for insert
writeQuery.setTranslationRow(modifyRow);
if (!descriptor.isAggregateCollectionDescriptor()) {// Should/cannot be recomputed in aggregate collection.
writeQuery.setPrimaryKey(descriptor.getObjectBuilder().extractPrimaryKeyFromObject(object, session));
}
addWriteLockFieldForInsert();
// CR#3237
// Store the size of the modify row so we can determine if the user has added to the row in the insert.
int modifyRowSize = modifyRow.size();
// PERF: Avoid events if no listeners.
if (eventManager.hasAnyEventListeners()) {
DescriptorEvent event = new DescriptorEvent(DescriptorEventManager.AboutToInsertEvent, writeQuery);
event.setRecord(modifyRow);
eventManager.executeEvent(event);
}
if (QueryMonitor.shouldMonitor()) {
QueryMonitor.incrementInsert(writeQuery);
}
// CR#3237
// Call insert with a boolean that tells it to reprepare if the user has altered the modify row.
insertObject(modifyRowSize != modifyRow.size());
// register the object before post insert to resolve possible cycles
registerObjectInIdentityMap(object, descriptor, session);
}
commitManager.markPostModifyCommitInProgress(object);
// Verify if deep shallow modify is turned on.
if (writeQuery.shouldCascadeParts()) {
queryManager.postInsert(writeQuery);
}
if ((descriptor.getHistoryPolicy() != null) && descriptor.getHistoryPolicy().shouldHandleWrites()) {
descriptor.getHistoryPolicy().postInsert(writeQuery);
}