@Override public void doBeforeTransactionCompletion(SessionImplementor session) { final EntityPersister persister = entry.getPersister(); final Object latestVersion = persister.getCurrentVersion(entry.getId(), session); if (!entry.getVersion().equals(latestVersion)) { throw new OptimisticLockException( object, "Newer version [" + latestVersion + "] of entity [" + MessageHelper.infoString(entry.getEntityName(), entry.getId()) + "] found in database"); } }
/** * process cascade save/update at the start of a flush to discover any newly referenced entity * that must be passed to saveOrUpdate(), and also apply orphan delete */ private void prepareEntityFlushes(EventSource session, PersistenceContext persistenceContext) throws HibernateException { LOG.debug("Processing flush-time cascades"); final Object anything = getAnything(); // safe from concurrent modification because of how concurrentEntries() is implemented on // IdentityMap for (Map.Entry<Object, EntityEntry> me : persistenceContext.reentrantSafeEntityEntries()) { // for ( Map.Entry me : IdentityMap.concurrentEntries( persistenceContext.getEntityEntries() // ) ) { EntityEntry entry = (EntityEntry) me.getValue(); Status status = entry.getStatus(); if (status == Status.MANAGED || status == Status.SAVING || status == Status.READ_ONLY) { cascadeOnFlush(session, entry.getPersister(), me.getKey(), anything); } } }
/** * process cascade save/update at the start of a flush to discover any newly referenced entity * that must be passed to saveOrUpdate(), and also apply orphan delete */ private void prepareEntityFlushes(EventSource session) throws HibernateException { LOG.debugf("Processing flush-time cascades"); final Map.Entry[] list = IdentityMap.concurrentEntries(session.getPersistenceContext().getEntityEntries()); // safe from concurrent modification because of how entryList() is implemented on IdentityMap final int size = list.length; final Object anything = getAnything(); for (int i = 0; i < size; i++) { Map.Entry me = list[i]; EntityEntry entry = (EntityEntry) me.getValue(); Status status = entry.getStatus(); if (status == Status.MANAGED || status == Status.SAVING || status == Status.READ_ONLY) { cascadeOnFlush(session, entry.getPersister(), me.getKey(), anything); } } }
/** * Handle the given delete event. This is the cascaded form. * * @param event The delete event. * @param transientEntities The cache of entities already deleted * @throws HibernateException */ public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException { final EventSource source = event.getSession(); final PersistenceContext persistenceContext = source.getPersistenceContext(); Object entity = persistenceContext.unproxyAndReassociate(event.getObject()); EntityEntry entityEntry = persistenceContext.getEntry(entity); final EntityPersister persister; final Serializable id; final Object version; if (entityEntry == null) { LOG.trace("Entity was not persistent in delete processing"); persister = source.getEntityPersister(event.getEntityName(), entity); if (ForeignKeys.isTransient(persister.getEntityName(), entity, null, source)) { deleteTransientEntity( source, entity, event.isCascadeDeleteEnabled(), persister, transientEntities); // EARLY EXIT!!! return; } performDetachedEntityDeletionCheck(event); id = persister.getIdentifier(entity, source); if (id == null) { throw new TransientObjectException( "the detached instance passed to delete() had a null identifier"); } final EntityKey key = source.generateEntityKey(id, persister); persistenceContext.checkUniqueness(key, entity); new OnUpdateVisitor(source, id, entity).process(entity, persister); version = persister.getVersion(entity); entityEntry = persistenceContext.addEntity( entity, (persister.isMutable() ? Status.MANAGED : Status.READ_ONLY), persister.getPropertyValues(entity), key, version, LockMode.NONE, true, persister, false); } else { LOG.trace("Deleting a persistent instance"); if (entityEntry.getStatus() == Status.DELETED || entityEntry.getStatus() == Status.GONE) { LOG.trace("Object was already deleted"); return; } persister = entityEntry.getPersister(); id = entityEntry.getId(); version = entityEntry.getVersion(); } /*if ( !persister.isMutable() ) { throw new HibernateException( "attempted to delete an object of immutable class: " + MessageHelper.infoString(persister) ); }*/ if (invokeDeleteLifecycle(source, entity, persister)) { return; } deleteEntity( source, entity, entityEntry, event.isCascadeDeleteEnabled(), event.isOrphanRemovalBeforeUpdates(), persister, transientEntities); if (source.getFactory().getSettings().isIdentifierRollbackEnabled()) { persister.resetIdentifier(entity, id, version, source); } }