HHH-18196 Remove Session#save / Session#update / Session#saveOrUpdate

This commit is contained in:
Andrea Boriero 2024-07-24 19:38:10 +02:00 committed by Steve Ebersole
parent 5699ed9b40
commit 83a226c503
22 changed files with 10 additions and 823 deletions

View File

@ -264,7 +264,6 @@ public interface Interceptor {
* *
* @see Session#persist(Object) * @see Session#persist(Object)
* @see Session#merge(Object) * @see Session#merge(Object)
* @see Session#save(Object)
* *
* @deprecated Use {@link #onPersist(Object, Object, Object[], String[], Type[])} * @deprecated Use {@link #onPersist(Object, Object, Object[], String[], Type[])}
*/ */

View File

@ -620,106 +620,6 @@ public interface Session extends SharedSessionContract, EntityManager {
@Deprecated( since = "6.0" ) @Deprecated( since = "6.0" )
void replicate(String entityName, Object object, ReplicationMode replicationMode) ; void replicate(String entityName, Object object, ReplicationMode replicationMode) ;
/**
* Persist the given transient instance, first assigning a generated identifier.
* (Or using the current value of the identifier property if the {@code assigned}
* generator is used.) This operation cascades to associated instances if the
* association is mapped with
* {@link org.hibernate.annotations.CascadeType#SAVE_UPDATE}.
* <p>
* This operation is very similar to {@link #persist(Object)}.
*
* @param object a transient instance of a persistent class
*
* @return the generated identifier
*
* @deprecated use {@link #persist(Object)}
*/
@Deprecated(since = "6.0")
Object save(Object object);
/**
* Persist the given transient instance, first assigning a generated identifier.
* (Or using the current value of the identifier property if the {@code assigned}
* generator is used.) This operation cascades to associated instances if the
* association is mapped with {@link org.hibernate.annotations.CascadeType#SAVE_UPDATE}.
*
* @param entityName the entity name
* @param object a transient instance of a persistent class
*
* @return the generated identifier
*
* @deprecated use {@link #persist(String, Object)}
*/
@Deprecated(since = "6.0")
Object save(String entityName, Object object);
/**
* Either {@link #save(Object)} or {@link #update(Object)} the given
* instance, depending upon resolution of the unsaved-value checks (see the
* manual for discussion of unsaved-value checking).
* <p>
* This operation cascades to associated instances if the association is mapped
* with {@link org.hibernate.annotations.CascadeType#SAVE_UPDATE}.
*
* @param object a transient or detached instance containing new or updated state
*
* @see Session#save(Object)
* @see Session#update(Object object)
*
* @deprecated use {@link #merge(String, Object)} or {@link #persist(Object)}
*/
@Deprecated(since = "6.0")
void saveOrUpdate(Object object);
/**
* Either {@link #save(String, Object)} or {@link #update(String, Object)}
* the given instance, depending upon resolution of the unsaved-value checks
* (see the manual for discussion of unsaved-value checking).
* <p>
* This operation cascades to associated instances if the association is mapped
* with {@link org.hibernate.annotations.CascadeType#SAVE_UPDATE}.
*
* @param entityName the entity name
* @param object a transient or detached instance containing new or updated state
*
* @see Session#save(String,Object)
* @see Session#update(String,Object)
*
* @deprecated use {@link #merge(String, Object)} or {@link #persist(String, Object)}
*/
@Deprecated(since = "6.0")
void saveOrUpdate(String entityName, Object object);
/**
* Update the persistent instance with the identifier of the given detached
* instance. If there is a persistent instance with the same identifier,
* an exception is thrown. This operation cascades to associated instances
* if the association is mapped with
* {@link org.hibernate.annotations.CascadeType#SAVE_UPDATE}.
*
* @param object a detached instance containing updated state
*
* @deprecated use {@link #merge(Object)}
*/
@Deprecated(since = "6.0")
void update(Object object);
/**
* Update the persistent instance with the identifier of the given detached
* instance. If there is a persistent instance with the same identifier,
* an exception is thrown. This operation cascades to associated instances
* if the association is mapped with
* {@link org.hibernate.annotations.CascadeType#SAVE_UPDATE}.
*
* @param entityName the entity name
* @param object a detached instance containing updated state
*
* @deprecated use {@link #merge(String, Object)}
*/
@Deprecated(since = "6.0")
void update(String entityName, Object object);
/** /**
* Copy the state of the given object onto the persistent object with the same * Copy the state of the given object onto the persistent object with the same
* identifier. If there is no persistent instance currently associated with * identifier. If there is no persistent instance currently associated with

View File

@ -95,17 +95,6 @@ public enum CascadeType {
@Deprecated @Deprecated
DELETE, DELETE,
/**
* A cascade type for the {@code saveOrUpdate()} operation.
*
* @see org.hibernate.Session#saveOrUpdate(Object)
*
* @deprecated since {@link org.hibernate.Session#saveOrUpdate(Object)}
* is deprecated
*/
@Deprecated
SAVE_UPDATE,
/** /**
* A cascade type for the {@code replicate()} operation. * A cascade type for the {@code replicate()} operation.
* *

View File

@ -1019,10 +1019,6 @@ public class BinderHelper {
case DELETE_ORPHAN: case DELETE_ORPHAN:
cascade.append( "," ).append( "delete-orphan" ); cascade.append( "," ).append( "delete-orphan" );
break; break;
case SAVE_UPDATE:
warnAboutDeprecatedCascadeType( CascadeType.SAVE_UPDATE );
cascade.append( "," ).append( "save-update" );
break;
case REPLICATE: case REPLICATE:
warnAboutDeprecatedCascadeType( CascadeType.REPLICATE ); warnAboutDeprecatedCascadeType( CascadeType.REPLICATE );
cascade.append( "," ).append( "replicate" ); cascade.append( "," ).append( "replicate" );

View File

@ -62,22 +62,6 @@ public final class CascadeStyles {
} }
}; };
/**
* save / update
*/
public static final CascadeStyle UPDATE = new BaseCascadeStyle() {
@Override
public boolean doCascade(CascadingAction action) {
return action == CascadingActions.SAVE_UPDATE
|| action == CascadingActions.CHECK_ON_FLUSH;
}
@Override
public String toString() {
return "STYLE_SAVE_UPDATE";
}
};
/** /**
* lock * lock
*/ */
@ -197,7 +181,6 @@ public final class CascadeStyles {
@Override @Override
public boolean doCascade(CascadingAction action) { public boolean doCascade(CascadingAction action) {
return action == CascadingActions.REMOVE return action == CascadingActions.REMOVE
|| action == CascadingActions.SAVE_UPDATE
|| action == CascadingActions.PERSIST_ON_FLUSH || action == CascadingActions.PERSIST_ON_FLUSH
|| action == CascadingActions.CHECK_ON_FLUSH; || action == CascadingActions.CHECK_ON_FLUSH;
} }
@ -241,7 +224,6 @@ public final class CascadeStyles {
base.put( "all", ALL ); base.put( "all", ALL );
base.put( "all-delete-orphan", ALL_DELETE_ORPHAN ); base.put( "all-delete-orphan", ALL_DELETE_ORPHAN );
base.put( "save-update", UPDATE );
base.put( "persist", PERSIST ); base.put( "persist", PERSIST );
base.put( "merge", MERGE ); base.put( "merge", MERGE );
base.put( "lock", LOCK ); base.put( "lock", LOCK );

View File

@ -200,48 +200,6 @@ public class CascadingActions {
} }
}; };
/**
* @see org.hibernate.Session#saveOrUpdate(Object)
*/
public static final CascadingAction<PersistContext> SAVE_UPDATE = new BaseCascadingAction<>() {
@Override
public void cascade(
EventSource session,
Object child,
String entityName,
PersistContext nothing,
boolean isCascadeDeleteEnabled)
throws HibernateException {
LOG.tracev( "Cascading to save or update: {0}", entityName );
session.saveOrUpdate( entityName, child );
}
@Override
public Iterator<?> getCascadableChildrenIterator(
EventSource session,
CollectionType collectionType,
Object collection) {
// saves / updates don't cascade to uninitialized collections
return getLoadedElementsIterator( session, collectionType, collection );
}
@Override
public boolean deleteOrphans() {
// orphans should be deleted during save/update
return true;
}
@Override
public boolean performOnLazyProperty() {
return false;
}
@Override
public String toString() {
return "ACTION_SAVE_UPDATE";
}
};
/** /**
* @see org.hibernate.Session#merge(Object) * @see org.hibernate.Session#merge(Object)
*/ */

View File

@ -36,7 +36,6 @@ import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.event.spi.AutoFlushEvent;
import org.hibernate.event.spi.EventManager; import org.hibernate.event.spi.EventManager;
import org.hibernate.event.spi.DeleteContext; import org.hibernate.event.spi.DeleteContext;
import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventSource;
@ -858,36 +857,6 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
delegate.replicate( entityName, object, replicationMode ); delegate.replicate( entityName, object, replicationMode );
} }
@Override
public Object save(Object object) {
return delegate.save( object );
}
@Override
public Object save(String entityName, Object object) {
return delegate.save( entityName, object );
}
@Override
public void saveOrUpdate(Object object) {
delegate.saveOrUpdate( object );
}
@Override
public void saveOrUpdate(String entityName, Object object) {
delegate.saveOrUpdate( entityName, object );
}
@Override
public void update(Object object) {
delegate.update( object );
}
@Override
public void update(String entityName, Object object) {
delegate.update( entityName, object );
}
@Override @Override
public <T> T merge(T object) { public <T> T merge(T object) {
return delegate.merge( object ); return delegate.merge( object );

View File

@ -239,42 +239,6 @@ public class SessionLazyDelegator implements Session {
this.lazySession.get().replicate( entityName, object, replicationMode ); this.lazySession.get().replicate( entityName, object, replicationMode );
} }
@Override
@Deprecated
public Object save(Object object) {
return this.lazySession.get().save( object );
}
@Override
@Deprecated
public Object save(String entityName, Object object) {
return this.lazySession.get().save( entityName, object );
}
@Override
@Deprecated
public void saveOrUpdate(Object object) {
this.lazySession.get().saveOrUpdate( object );
}
@Override
@Deprecated
public void saveOrUpdate(String entityName, Object object) {
this.lazySession.get().saveOrUpdate( entityName, object );
}
@Override
@Deprecated
public void update(Object object) {
this.lazySession.get().update( object );
}
@Override
@Deprecated
public void update(String entityName, Object object) {
this.lazySession.get().update( entityName, object );
}
@Override @Override
public <T> T merge(T object) { public <T> T merge(T object) {
return this.lazySession.get().merge( object ); return this.lazySession.get().merge( object );

View File

@ -198,13 +198,11 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
} }
protected PersistContext getContext(EventSource session) { protected PersistContext getContext(EventSource session) {
return jpaBootstrap || isJpaCascadeComplianceEnabled( session ) ? PersistContext.create() : null; return PersistContext.create();
} }
protected CascadingAction<PersistContext> getCascadingAction(EventSource session) { protected CascadingAction<PersistContext> getCascadingAction(EventSource session) {
return jpaBootstrap || isJpaCascadeComplianceEnabled( session ) return CascadingActions.PERSIST_ON_FLUSH;
? CascadingActions.PERSIST_ON_FLUSH
: CascadingActions.SAVE_UPDATE;
} }
private static boolean isJpaCascadeComplianceEnabled(EventSource session) { private static boolean isJpaCascadeComplianceEnabled(EventSource session) {

View File

@ -1,45 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.event.internal;
import org.hibernate.Hibernate;
import org.hibernate.PersistentObjectException;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.event.spi.SaveOrUpdateEvent;
/**
* An event handler for save() events
*
* @author Gavin King
*
* @deprecated since {@link org.hibernate.Session#save} is deprecated
*/
@Deprecated(since="6")
public class DefaultSaveEventListener extends DefaultSaveOrUpdateEventListener {
@Override
protected Object performSaveOrUpdate(SaveOrUpdateEvent event) {
// this implementation is supposed to tolerate incorrect unsaved-value
// mappings, for the purpose of backward-compatibility
final EntityEntry entry = event.getSession().getPersistenceContextInternal().getEntry( event.getEntity() );
return entry != null && entry.getStatus() != Status.DELETED
? entityIsPersistent( event )
: entityIsTransient( event );
}
@Override
protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) {
if ( !Hibernate.isInitialized( object ) ) {
throw new PersistentObjectException("uninitialized proxy passed to save()");
}
else {
return false;
}
}
}

View File

@ -1,340 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.event.internal;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.PersistentObjectException;
import org.hibernate.TransientObjectException;
import org.hibernate.classic.Lifecycle;
import org.hibernate.engine.internal.Cascade;
import org.hibernate.engine.internal.CascadePoint;
import org.hibernate.engine.spi.CascadingAction;
import org.hibernate.engine.spi.CascadingActions;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.PersistContext;
import org.hibernate.event.spi.SaveOrUpdateEvent;
import org.hibernate.event.spi.SaveOrUpdateEventListener;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
/**
* Defines the default listener used by Hibernate for handling save-update
* events.
*
* @author Steve Ebersole
* @author Gavin King
*
* @deprecated since {@link org.hibernate.Session#saveOrUpdate} is deprecated
*/
@Deprecated(since="6")
public class DefaultSaveOrUpdateEventListener
extends AbstractSaveEventListener<PersistContext>
implements SaveOrUpdateEventListener {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultSaveOrUpdateEventListener.class );
/**
* Handle the given update event.
*
* @param event The update event to be handled.
*/
@Override
public void onSaveOrUpdate(SaveOrUpdateEvent event) {
final Object object = event.getObject();
final Object requestedId = event.getRequestedId();
if ( requestedId != null ) {
//assign the requested id to the proxy, *before*
//reassociating the proxy
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
if ( lazyInitializer != null ) {
lazyInitializer.setIdentifier( requestedId );
}
}
final SessionImplementor source = event.getSession();
// For an uninitialized proxy, noop, don't even need to return an id, since it is never a save()
if ( reassociateIfUninitializedProxy( object, source ) ) {
LOG.trace( "Reassociated uninitialized proxy" );
}
else {
//initialize properties of the event:
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
final Object entity = persistenceContext.unproxyAndReassociate( object );
event.setEntity( entity );
event.setEntry( persistenceContext.getEntry( entity ) );
//return the id in the event object
event.setResultId( performSaveOrUpdate( event ) );
}
}
protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) {
return source.getPersistenceContextInternal().reassociateIfUninitializedProxy( object );
}
protected Object performSaveOrUpdate(SaveOrUpdateEvent event) {
final EntityState entityState = EntityState.getEntityState(
event.getEntity(),
event.getEntityName(),
event.getEntry(),
event.getSession(),
null
);
switch ( entityState ) {
case DETACHED:
entityIsDetached( event );
return null;
case PERSISTENT:
return entityIsPersistent( event );
default: //TRANSIENT or DELETED
return entityIsTransient( event );
}
}
protected Object entityIsPersistent(SaveOrUpdateEvent event) throws HibernateException {
if ( LOG.isTraceEnabled() ) {
LOG.trace( "Ignoring persistent instance" );
}
EntityEntry entityEntry = event.getEntry();
if ( entityEntry == null ) {
throw new AssertionFailure( "entity was transient or detached" );
}
else {
if ( entityEntry.getStatus() == Status.DELETED ) {
throw new AssertionFailure( "entity was deleted" );
}
final SessionFactoryImplementor factory = event.getFactory();
final Object requestedId = event.getRequestedId();
final Object savedId;
if ( requestedId == null ) {
savedId = entityEntry.getId();
}
else {
final boolean isEqual = entityEntry.getPersister().getIdentifierType()
.isEqual( requestedId, entityEntry.getId(), factory );
if ( isEqual ) {
throw new PersistentObjectException(
"object passed to save() was already persistent: " +
MessageHelper.infoString( entityEntry.getPersister(), requestedId, factory )
);
}
savedId = requestedId;
}
if ( LOG.isTraceEnabled() ) {
LOG.tracev(
"Object already associated with session: {0}",
MessageHelper.infoString( entityEntry.getPersister(), savedId, factory )
);
}
return savedId;
}
}
/**
* The given save-update event named a transient entity.
* <p>
* Here, we will perform the save processing.
*
* @param event The save event to be handled.
*
* @return The entity's identifier after saving.
*/
protected Object entityIsTransient(SaveOrUpdateEvent event) {
LOG.trace( "Saving transient instance" );
final EventSource source = event.getSession();
final EntityEntry entityEntry = event.getEntry();
if ( entityEntry != null ) {
if ( entityEntry.getStatus() == Status.DELETED ) {
source.forceFlush( entityEntry );
}
else {
throw new AssertionFailure( "entity was persistent" );
}
}
if ( event.getRequestedId() != null ) {
throw new AssertionFailure( "requested id should be null in save" );
}
final Object id = saveWithGeneratedId(
event.getEntity(),
event.getEntityName(),
null,
event.getSession(),
true
);
source.getPersistenceContextInternal().reassociateProxy( event.getObject(), id );
return id;
}
/**
* The given save-update event named a detached entity.
* <p>
* Here, we will perform the update processing.
*
* @param event The update event to be handled.
*/
protected void entityIsDetached(SaveOrUpdateEvent event) {
LOG.trace( "Updating detached instance" );
final EventSource session = event.getSession();
if ( session.getPersistenceContextInternal().isEntryFor( event.getEntity() ) ) {
//TODO: assertion only, could be optimized away
throw new AssertionFailure( "entity was persistent" );
}
final Object entity = event.getEntity();
final EntityPersister persister = session.getEntityPersister( event.getEntityName(), entity );
event.setRequestedId( getUpdateId( entity, persister, event.getRequestedId(), session ) );
performUpdate( event, entity, persister );
}
/**
* Determine the id to use for updating.
*
* @param entity The entity.
* @param persister The entity persister
* @param requestedId The requested identifier
* @param session The session
*
* @return The id.
*
* @throws TransientObjectException If the entity is considered transient.
*/
protected Object getUpdateId(Object entity, EntityPersister persister, Object requestedId, SessionImplementor session) {
// use the id assigned to the instance
final Object id = persister.getIdentifier( entity, session );
if ( id == null ) {
// assume this is a newly instantiated transient object
// which should be saved rather than updated
throw new TransientObjectException( "The given object has a null identifier: "
+ persister.getEntityName() );
}
else {
return id;
}
}
protected void performUpdate(SaveOrUpdateEvent event, Object entity, EntityPersister persister)
throws HibernateException {
final EventSource source = event.getSession();
if ( LOG.isTraceEnabled() ) {
if ( !persister.isMutable() ) {
LOG.trace( "Immutable instance passed to performUpdate()" );
}
LOG.tracev(
"Updating {0}",
MessageHelper.infoString( persister, event.getRequestedId(), event.getFactory() )
);
}
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
final EntityKey key = source.generateEntityKey( event.getRequestedId(), persister );
persistenceContext.checkUniqueness( key, entity );
if ( invokeUpdateLifecycle( entity, persister, source ) ) {
reassociate( event, event.getObject(), event.getRequestedId(), persister );
}
else {
// this is a transient object with existing persistent state not loaded by the session
new OnUpdateVisitor( source, event.getRequestedId(), entity ).process( entity, persister );
// TODO: put this stuff back in to read snapshot from
// the second-level cache (needs some extra work)
// Object[] cachedState = null;
// if ( persister.hasCache() ) {
// CacheEntry entry = (CacheEntry) persister.getCache()
// .get( event.getRequestedId(), source.getTimestamp() );
// cachedState = entry==null ?
// null :
// entry.getState(); //TODO: half-assemble this stuff
// }
persistenceContext.addEntity(
entity,
persister.isMutable() ? Status.MANAGED : Status.READ_ONLY,
null, // cachedState,
key,
persister.getVersion( entity ),
LockMode.NONE,
true,
persister,
false
);
persister.afterReassociate( entity, source );
if ( LOG.isTraceEnabled() ) {
LOG.tracev(
"Updating {0}",
MessageHelper.infoString( persister, event.getRequestedId(), event.getFactory() )
);
}
cascadeOnUpdate( event, persister, entity );
}
}
protected boolean invokeUpdateLifecycle(Object entity, EntityPersister persister, EventSource source) {
if ( persister.implementsLifecycle() ) {
LOG.debug( "Calling onUpdate()" );
if ( ( (Lifecycle) entity ).onUpdate( source ) ) {
LOG.debug( "Update vetoed by onUpdate()" );
return true;
}
}
return false;
}
/**
* Handles the calls needed to perform cascades as part of an update request
* for the given entity.
*
* @param event The event currently being processed.
* @param persister The defined persister for the entity being updated.
* @param entity The entity being updated.
*/
private void cascadeOnUpdate(SaveOrUpdateEvent event, EntityPersister persister, Object entity) {
final EventSource source = event.getSession();
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
persistenceContext.incrementCascadeLevel();
try {
Cascade.cascade( CascadingActions.SAVE_UPDATE, CascadePoint.AFTER_UPDATE, source, persister, entity );
}
finally {
persistenceContext.decrementCascadeLevel();
}
}
@Override
protected CascadingAction<PersistContext> getCascadeAction() {
return CascadingActions.SAVE_UPDATE;
}
}

View File

@ -1,62 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.event.internal;
import org.hibernate.HibernateException;
import org.hibernate.ObjectDeletedException;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.event.spi.SaveOrUpdateEvent;
import org.hibernate.persister.entity.EntityPersister;
/**
* An event handler for update() events
*
* @author Gavin King
*
* @deprecated since {@link org.hibernate.Session#update} is deprecated
*/
@Deprecated(since="6")
public class DefaultUpdateEventListener extends DefaultSaveOrUpdateEventListener {
@Override
protected Object performSaveOrUpdate(SaveOrUpdateEvent event) {
// this implementation is supposed to tolerate incorrect unsaved-value
// mappings, for the purpose of backward-compatibility
EntityEntry entry = event.getSession().getPersistenceContextInternal().getEntry( event.getEntity() );
if ( entry!=null ) {
if ( entry.getStatus() == Status.DELETED ) {
throw new ObjectDeletedException( "deleted instance passed to update()", null, event.getEntityName() );
}
else {
return entityIsPersistent( event );
}
}
else {
entityIsDetached( event );
return null;
}
}
/**
* If the user specified an id, assign it to the instance and use that,
* otherwise use the id already assigned to the instance
*/
@Override
protected Object getUpdateId(Object entity, EntityPersister persister, Object requestedId, SessionImplementor session)
throws HibernateException {
if ( requestedId == null ) {
return super.getUpdateId( entity, persister, null, session );
}
else {
persister.setIdentifier( entity, requestedId, session );
return requestedId;
}
}
}

View File

@ -32,9 +32,6 @@ import org.hibernate.event.internal.DefaultPreLoadEventListener;
import org.hibernate.event.internal.DefaultRefreshEventListener; import org.hibernate.event.internal.DefaultRefreshEventListener;
import org.hibernate.event.internal.DefaultReplicateEventListener; import org.hibernate.event.internal.DefaultReplicateEventListener;
import org.hibernate.event.internal.DefaultResolveNaturalIdEventListener; import org.hibernate.event.internal.DefaultResolveNaturalIdEventListener;
import org.hibernate.event.internal.DefaultSaveEventListener;
import org.hibernate.event.internal.DefaultSaveOrUpdateEventListener;
import org.hibernate.event.internal.DefaultUpdateEventListener;
import org.hibernate.event.internal.PostDeleteEventListenerStandardImpl; import org.hibernate.event.internal.PostDeleteEventListenerStandardImpl;
import org.hibernate.event.internal.PostInsertEventListenerStandardImpl; import org.hibernate.event.internal.PostInsertEventListenerStandardImpl;
import org.hibernate.event.internal.PostUpdateEventListenerStandardImpl; import org.hibernate.event.internal.PostUpdateEventListenerStandardImpl;
@ -81,9 +78,6 @@ import static org.hibernate.event.spi.EventType.PRE_UPSERT;
import static org.hibernate.event.spi.EventType.REFRESH; import static org.hibernate.event.spi.EventType.REFRESH;
import static org.hibernate.event.spi.EventType.REPLICATE; import static org.hibernate.event.spi.EventType.REPLICATE;
import static org.hibernate.event.spi.EventType.RESOLVE_NATURAL_ID; import static org.hibernate.event.spi.EventType.RESOLVE_NATURAL_ID;
import static org.hibernate.event.spi.EventType.SAVE;
import static org.hibernate.event.spi.EventType.SAVE_UPDATE;
import static org.hibernate.event.spi.EventType.UPDATE;
/** /**
* Standard implementation of EventListenerRegistry * Standard implementation of EventListenerRegistry
@ -317,20 +311,11 @@ public class EventListenerRegistryImpl implements EventListenerRegistry {
// post-upsert listeners // post-upsert listeners
prepareListeners( POST_UPSERT, new PostUpsertEventListenerStandardImpl() ); prepareListeners( POST_UPSERT, new PostUpsertEventListenerStandardImpl() );
// update listeners
prepareListeners( UPDATE, new DefaultUpdateEventListener() );
// refresh listeners // refresh listeners
prepareListeners( REFRESH, new DefaultRefreshEventListener() ); prepareListeners( REFRESH, new DefaultRefreshEventListener() );
// replicate listeners // replicate listeners
prepareListeners( REPLICATE, new DefaultReplicateEventListener() ); prepareListeners( REPLICATE, new DefaultReplicateEventListener() );
// save listeners
prepareListeners( SAVE, new DefaultSaveEventListener() );
// save-update listeners
prepareListeners( SAVE_UPDATE, new DefaultSaveOrUpdateEventListener() );
} }
public <T> void prepareListeners(EventType<T> eventType) { public <T> void prepareListeners(EventType<T> eventType) {

View File

@ -31,9 +31,6 @@ public final class EventType<T> {
public static final EventType<InitializeCollectionEventListener> INIT_COLLECTION = create( "load-collection", InitializeCollectionEventListener.class ); public static final EventType<InitializeCollectionEventListener> INIT_COLLECTION = create( "load-collection", InitializeCollectionEventListener.class );
public static final EventType<SaveOrUpdateEventListener> SAVE_UPDATE = create( "save-update", SaveOrUpdateEventListener.class );
public static final EventType<SaveOrUpdateEventListener> UPDATE = create( "update", SaveOrUpdateEventListener.class );
public static final EventType<SaveOrUpdateEventListener> SAVE = create( "save", SaveOrUpdateEventListener.class );
public static final EventType<PersistEventListener> PERSIST = create( "create", PersistEventListener.class ); public static final EventType<PersistEventListener> PERSIST = create( "create", PersistEventListener.class );
public static final EventType<PersistEventListener> PERSIST_ONFLUSH = create( "create-onflush", PersistEventListener.class ); public static final EventType<PersistEventListener> PERSIST_ONFLUSH = create( "create-onflush", PersistEventListener.class );

View File

@ -1,28 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.event.spi;
import org.hibernate.HibernateException;
/**
* Defines the contract for handling of update events generated from a session.
*
* @author Steve Ebersole
*
* @deprecated since {@link org.hibernate.Session#saveOrUpdate} and friends are deprecated
*/
@Deprecated(since="6")
public interface SaveOrUpdateEventListener {
/**
* Handle the given update event.
*
* @param event The update event to be handled.
*/
void onSaveOrUpdate(SaveOrUpdateEvent event) throws HibernateException;
}

View File

@ -159,7 +159,8 @@ public final class IdentifierGeneratorHelper {
} }
catch (TransientObjectException toe) { catch (TransientObjectException toe) {
if ( sessionImplementor.isSessionImplementor() ) { if ( sessionImplementor.isSessionImplementor() ) {
return sessionImplementor.asSessionImplementor().save( associatedEntityName, associatedEntity ); sessionImplementor.asSessionImplementor().persist( associatedEntityName, associatedEntity );
return sessionImplementor.getContextEntityIdentifier( associatedEntity );
} }
else if ( sessionImplementor.isStatelessSession() ) { else if ( sessionImplementor.isStatelessSession() ) {
return sessionImplementor.asStatelessSession().insert( associatedEntityName, associatedEntity ); return sessionImplementor.asStatelessSession().insert( associatedEntityName, associatedEntity );

View File

@ -63,7 +63,6 @@ import org.hibernate.event.spi.PreUpsertEventListener;
import org.hibernate.event.spi.RefreshEventListener; import org.hibernate.event.spi.RefreshEventListener;
import org.hibernate.event.spi.ReplicateEventListener; import org.hibernate.event.spi.ReplicateEventListener;
import org.hibernate.event.spi.ResolveNaturalIdEventListener; import org.hibernate.event.spi.ResolveNaturalIdEventListener;
import org.hibernate.event.spi.SaveOrUpdateEventListener;
import org.hibernate.jpa.HibernateHints; import org.hibernate.jpa.HibernateHints;
import org.hibernate.jpa.LegacySpecHints; import org.hibernate.jpa.LegacySpecHints;
import org.hibernate.jpa.SpecHints; import org.hibernate.jpa.SpecHints;
@ -154,9 +153,6 @@ public final class FastSessionServices {
public final EventListenerGroup<RefreshEventListener> eventListenerGroup_REFRESH; public final EventListenerGroup<RefreshEventListener> eventListenerGroup_REFRESH;
public final EventListenerGroup<ReplicateEventListener> eventListenerGroup_REPLICATE; public final EventListenerGroup<ReplicateEventListener> eventListenerGroup_REPLICATE;
public final EventListenerGroup<ResolveNaturalIdEventListener> eventListenerGroup_RESOLVE_NATURAL_ID; public final EventListenerGroup<ResolveNaturalIdEventListener> eventListenerGroup_RESOLVE_NATURAL_ID;
public final EventListenerGroup<SaveOrUpdateEventListener> eventListenerGroup_SAVE;
public final EventListenerGroup<SaveOrUpdateEventListener> eventListenerGroup_SAVE_UPDATE;
public final EventListenerGroup<SaveOrUpdateEventListener> eventListenerGroup_UPDATE;
//Intentionally Package private: //Intentionally Package private:
final boolean disallowOutOfTransactionUpdateOperations; final boolean disallowOutOfTransactionUpdateOperations;
@ -236,9 +232,6 @@ public final class FastSessionServices {
this.eventListenerGroup_REFRESH = listeners( eventListenerRegistry, EventType.REFRESH ); this.eventListenerGroup_REFRESH = listeners( eventListenerRegistry, EventType.REFRESH );
this.eventListenerGroup_REPLICATE = listeners( eventListenerRegistry, EventType.REPLICATE ); this.eventListenerGroup_REPLICATE = listeners( eventListenerRegistry, EventType.REPLICATE );
this.eventListenerGroup_RESOLVE_NATURAL_ID = listeners( eventListenerRegistry, EventType.RESOLVE_NATURAL_ID ); this.eventListenerGroup_RESOLVE_NATURAL_ID = listeners( eventListenerRegistry, EventType.RESOLVE_NATURAL_ID );
this.eventListenerGroup_SAVE = listeners( eventListenerRegistry, EventType.SAVE );
this.eventListenerGroup_SAVE_UPDATE = listeners( eventListenerRegistry, EventType.SAVE_UPDATE );
this.eventListenerGroup_UPDATE = listeners( eventListenerRegistry, EventType.UPDATE );
//Other highly useful constants: //Other highly useful constants:
this.dialect = jdbcServices.getJdbcEnvironment().getDialect(); this.dialect = jdbcServices.getJdbcEnvironment().getDialect();

View File

@ -107,8 +107,6 @@ import org.hibernate.event.spi.ReplicateEvent;
import org.hibernate.event.spi.ReplicateEventListener; import org.hibernate.event.spi.ReplicateEventListener;
import org.hibernate.event.spi.ResolveNaturalIdEvent; import org.hibernate.event.spi.ResolveNaturalIdEvent;
import org.hibernate.event.spi.ResolveNaturalIdEventListener; import org.hibernate.event.spi.ResolveNaturalIdEventListener;
import org.hibernate.event.spi.SaveOrUpdateEvent;
import org.hibernate.event.spi.SaveOrUpdateEventListener;
import org.hibernate.graph.GraphSemantic; import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.RootGraph; import org.hibernate.graph.RootGraph;
import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.graph.spi.RootGraphImplementor;
@ -637,72 +635,6 @@ public class SessionImpl
super.checkOpenOrWaitingForAutoClose(); super.checkOpenOrWaitingForAutoClose();
} }
// saveOrUpdate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override @Deprecated
public void saveOrUpdate(Object object) throws HibernateException {
saveOrUpdate( null, object );
}
@Override @Deprecated
public void saveOrUpdate(String entityName, Object obj) throws HibernateException {
fireSaveOrUpdate( new SaveOrUpdateEvent( entityName, obj, this ) );
}
private void fireSaveOrUpdate(final SaveOrUpdateEvent event) {
checkOpen();
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
fastSessionServices.eventListenerGroup_SAVE_UPDATE
.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
checkNoUnresolvedActionsAfterOperation();
}
// save() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override @Deprecated
public Object save(Object obj) throws HibernateException {
return save( null, obj );
}
@Override @Deprecated
public Object save(String entityName, Object object) throws HibernateException {
return fireSave( new SaveOrUpdateEvent( entityName, object, this ) );
}
private Object fireSave(final SaveOrUpdateEvent event) {
checkOpen();
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
fastSessionServices.eventListenerGroup_SAVE
.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
checkNoUnresolvedActionsAfterOperation();
return event.getResultId();
}
// update() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override @Deprecated
public void update(Object obj) throws HibernateException {
update( null, obj );
}
@Override @Deprecated
public void update(String entityName, Object object) throws HibernateException {
fireUpdate( new SaveOrUpdateEvent( entityName, object, this ) );
}
private void fireUpdate(SaveOrUpdateEvent event) {
checkOpen();
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
fastSessionServices.eventListenerGroup_UPDATE
.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
checkNoUnresolvedActionsAfterOperation();
}
// lock() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // lock() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override @Override

View File

@ -59,7 +59,7 @@ public class DefaultRevisionInfoGenerator implements RevisionInfoGenerator {
@Override @Override
public void saveRevisionData(Session session, Object revisionData) { public void saveRevisionData(Session session, Object revisionData) {
session.save( revisionInfoEntityName, revisionData ); session.persist( revisionInfoEntityName, revisionData );
if ( revisionInfoNumberReader != null && revisionInfoNumberReader.getRevisionNumber( revisionData ).longValue() < 0 ) { if ( revisionInfoNumberReader != null && revisionInfoNumberReader.getRevisionNumber( revisionData ).longValue() < 0 ) {
throw new AuditException( "Negative revision numbers are not allowed" ); throw new AuditException( "Negative revision numbers are not allowed" );
} }

View File

@ -43,7 +43,7 @@ public class DefaultAuditStrategy implements AuditStrategy {
Object id, Object id,
Object data, Object data,
Object revision) { Object revision) {
session.save( configuration.getAuditEntityName( entityName ), data ); session.persist( configuration.getAuditEntityName( entityName ), data );
sessionCacheCleaner.scheduleAuditDataRemoval( session, data ); sessionCacheCleaner.scheduleAuditDataRemoval( session, data );
} }
@ -55,7 +55,7 @@ public class DefaultAuditStrategy implements AuditStrategy {
Configuration configuration, Configuration configuration,
PersistentCollectionChangeData persistentCollectionChangeData, PersistentCollectionChangeData persistentCollectionChangeData,
Object revision) { Object revision) {
session.save( persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData() ); session.persist( persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData() );
sessionCacheCleaner.scheduleAuditDataRemoval( session, persistentCollectionChangeData.getData() ); sessionCacheCleaner.scheduleAuditDataRemoval( session, persistentCollectionChangeData.getData() );
} }

View File

@ -163,7 +163,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
final String auditedEntityName = configuration.getAuditEntityName( entityName ); final String auditedEntityName = configuration.getAuditEntityName( entityName );
// Save the audit data // Save the audit data
session.save( auditedEntityName, data ); session.persist( auditedEntityName, data );
// Update the end date of the previous row. // Update the end date of the previous row.
// //
@ -271,7 +271,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
} }
// Save the audit data // Save the audit data
session.save( persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData() ); session.persist( persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData() );
sessionCacheCleaner.scheduleAuditDataRemoval( session, persistentCollectionChangeData.getData() ); sessionCacheCleaner.scheduleAuditDataRemoval( session, persistentCollectionChangeData.getData() );
} }
@ -375,7 +375,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
} }
// Saving the previous version // Saving the previous version
session.save( auditedEntityName, previousData ); session.persist( auditedEntityName, previousData );
sessionCacheCleaner.scheduleAuditDataRemoval( session, previousData ); sessionCacheCleaner.scheduleAuditDataRemoval( session, previousData );
} }
else { else {

View File

@ -68,7 +68,6 @@ final class StaticClassLists {
org.hibernate.event.spi.LoadEventListener[].class, org.hibernate.event.spi.LoadEventListener[].class,
org.hibernate.event.spi.ResolveNaturalIdEventListener[].class, org.hibernate.event.spi.ResolveNaturalIdEventListener[].class,
org.hibernate.event.spi.InitializeCollectionEventListener[].class, org.hibernate.event.spi.InitializeCollectionEventListener[].class,
org.hibernate.event.spi.SaveOrUpdateEventListener[].class,
org.hibernate.event.spi.PersistEventListener[].class, org.hibernate.event.spi.PersistEventListener[].class,
org.hibernate.event.spi.MergeEventListener[].class, org.hibernate.event.spi.MergeEventListener[].class,
org.hibernate.event.spi.DeleteEventListener[].class, org.hibernate.event.spi.DeleteEventListener[].class,