HHH-18196 Remove Session#save / Session#update / Session#saveOrUpdate
This commit is contained in:
parent
5699ed9b40
commit
83a226c503
|
@ -264,7 +264,6 @@ public interface Interceptor {
|
|||
*
|
||||
* @see Session#persist(Object)
|
||||
* @see Session#merge(Object)
|
||||
* @see Session#save(Object)
|
||||
*
|
||||
* @deprecated Use {@link #onPersist(Object, Object, Object[], String[], Type[])}
|
||||
*/
|
||||
|
|
|
@ -620,106 +620,6 @@ public interface Session extends SharedSessionContract, EntityManager {
|
|||
@Deprecated( since = "6.0" )
|
||||
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
|
||||
* identifier. If there is no persistent instance currently associated with
|
||||
|
|
|
@ -95,17 +95,6 @@ public enum CascadeType {
|
|||
@Deprecated
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -1019,10 +1019,6 @@ public class BinderHelper {
|
|||
case DELETE_ORPHAN:
|
||||
cascade.append( "," ).append( "delete-orphan" );
|
||||
break;
|
||||
case SAVE_UPDATE:
|
||||
warnAboutDeprecatedCascadeType( CascadeType.SAVE_UPDATE );
|
||||
cascade.append( "," ).append( "save-update" );
|
||||
break;
|
||||
case REPLICATE:
|
||||
warnAboutDeprecatedCascadeType( CascadeType.REPLICATE );
|
||||
cascade.append( "," ).append( "replicate" );
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
@ -197,7 +181,6 @@ public final class CascadeStyles {
|
|||
@Override
|
||||
public boolean doCascade(CascadingAction action) {
|
||||
return action == CascadingActions.REMOVE
|
||||
|| action == CascadingActions.SAVE_UPDATE
|
||||
|| action == CascadingActions.PERSIST_ON_FLUSH
|
||||
|| action == CascadingActions.CHECK_ON_FLUSH;
|
||||
}
|
||||
|
@ -241,7 +224,6 @@ public final class CascadeStyles {
|
|||
|
||||
base.put( "all", ALL );
|
||||
base.put( "all-delete-orphan", ALL_DELETE_ORPHAN );
|
||||
base.put( "save-update", UPDATE );
|
||||
base.put( "persist", PERSIST );
|
||||
base.put( "merge", MERGE );
|
||||
base.put( "lock", LOCK );
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.hibernate.engine.jdbc.LobCreator;
|
|||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.event.spi.AutoFlushEvent;
|
||||
import org.hibernate.event.spi.EventManager;
|
||||
import org.hibernate.event.spi.DeleteContext;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
|
@ -858,36 +857,6 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
|
|||
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
|
||||
public <T> T merge(T object) {
|
||||
return delegate.merge( object );
|
||||
|
|
|
@ -239,42 +239,6 @@ public class SessionLazyDelegator implements Session {
|
|||
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
|
||||
public <T> T merge(T object) {
|
||||
return this.lazySession.get().merge( object );
|
||||
|
|
|
@ -198,13 +198,11 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
}
|
||||
|
||||
protected PersistContext getContext(EventSource session) {
|
||||
return jpaBootstrap || isJpaCascadeComplianceEnabled( session ) ? PersistContext.create() : null;
|
||||
return PersistContext.create();
|
||||
}
|
||||
|
||||
protected CascadingAction<PersistContext> getCascadingAction(EventSource session) {
|
||||
return jpaBootstrap || isJpaCascadeComplianceEnabled( session )
|
||||
? CascadingActions.PERSIST_ON_FLUSH
|
||||
: CascadingActions.SAVE_UPDATE;
|
||||
return CascadingActions.PERSIST_ON_FLUSH;
|
||||
}
|
||||
|
||||
private static boolean isJpaCascadeComplianceEnabled(EventSource session) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -32,9 +32,6 @@ import org.hibernate.event.internal.DefaultPreLoadEventListener;
|
|||
import org.hibernate.event.internal.DefaultRefreshEventListener;
|
||||
import org.hibernate.event.internal.DefaultReplicateEventListener;
|
||||
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.PostInsertEventListenerStandardImpl;
|
||||
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.REPLICATE;
|
||||
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
|
||||
|
@ -317,20 +311,11 @@ public class EventListenerRegistryImpl implements EventListenerRegistry {
|
|||
// post-upsert listeners
|
||||
prepareListeners( POST_UPSERT, new PostUpsertEventListenerStandardImpl() );
|
||||
|
||||
// update listeners
|
||||
prepareListeners( UPDATE, new DefaultUpdateEventListener() );
|
||||
|
||||
// refresh listeners
|
||||
prepareListeners( REFRESH, new DefaultRefreshEventListener() );
|
||||
|
||||
// replicate listeners
|
||||
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) {
|
||||
|
|
|
@ -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<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_ONFLUSH = create( "create-onflush", PersistEventListener.class );
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -159,7 +159,8 @@ public final class IdentifierGeneratorHelper {
|
|||
}
|
||||
catch (TransientObjectException toe) {
|
||||
if ( sessionImplementor.isSessionImplementor() ) {
|
||||
return sessionImplementor.asSessionImplementor().save( associatedEntityName, associatedEntity );
|
||||
sessionImplementor.asSessionImplementor().persist( associatedEntityName, associatedEntity );
|
||||
return sessionImplementor.getContextEntityIdentifier( associatedEntity );
|
||||
}
|
||||
else if ( sessionImplementor.isStatelessSession() ) {
|
||||
return sessionImplementor.asStatelessSession().insert( associatedEntityName, associatedEntity );
|
||||
|
|
|
@ -63,7 +63,6 @@ import org.hibernate.event.spi.PreUpsertEventListener;
|
|||
import org.hibernate.event.spi.RefreshEventListener;
|
||||
import org.hibernate.event.spi.ReplicateEventListener;
|
||||
import org.hibernate.event.spi.ResolveNaturalIdEventListener;
|
||||
import org.hibernate.event.spi.SaveOrUpdateEventListener;
|
||||
import org.hibernate.jpa.HibernateHints;
|
||||
import org.hibernate.jpa.LegacySpecHints;
|
||||
import org.hibernate.jpa.SpecHints;
|
||||
|
@ -154,9 +153,6 @@ public final class FastSessionServices {
|
|||
public final EventListenerGroup<RefreshEventListener> eventListenerGroup_REFRESH;
|
||||
public final EventListenerGroup<ReplicateEventListener> eventListenerGroup_REPLICATE;
|
||||
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:
|
||||
final boolean disallowOutOfTransactionUpdateOperations;
|
||||
|
@ -236,9 +232,6 @@ public final class FastSessionServices {
|
|||
this.eventListenerGroup_REFRESH = listeners( eventListenerRegistry, EventType.REFRESH );
|
||||
this.eventListenerGroup_REPLICATE = listeners( eventListenerRegistry, EventType.REPLICATE );
|
||||
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:
|
||||
this.dialect = jdbcServices.getJdbcEnvironment().getDialect();
|
||||
|
|
|
@ -107,8 +107,6 @@ import org.hibernate.event.spi.ReplicateEvent;
|
|||
import org.hibernate.event.spi.ReplicateEventListener;
|
||||
import org.hibernate.event.spi.ResolveNaturalIdEvent;
|
||||
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.RootGraph;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
|
@ -637,72 +635,6 @@ public class SessionImpl
|
|||
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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
|
|
|
@ -59,7 +59,7 @@ public class DefaultRevisionInfoGenerator implements RevisionInfoGenerator {
|
|||
|
||||
@Override
|
||||
public void saveRevisionData(Session session, Object revisionData) {
|
||||
session.save( revisionInfoEntityName, revisionData );
|
||||
session.persist( revisionInfoEntityName, revisionData );
|
||||
if ( revisionInfoNumberReader != null && revisionInfoNumberReader.getRevisionNumber( revisionData ).longValue() < 0 ) {
|
||||
throw new AuditException( "Negative revision numbers are not allowed" );
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public class DefaultAuditStrategy implements AuditStrategy {
|
|||
Object id,
|
||||
Object data,
|
||||
Object revision) {
|
||||
session.save( configuration.getAuditEntityName( entityName ), data );
|
||||
session.persist( configuration.getAuditEntityName( entityName ), data );
|
||||
sessionCacheCleaner.scheduleAuditDataRemoval( session, data );
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ public class DefaultAuditStrategy implements AuditStrategy {
|
|||
Configuration configuration,
|
||||
PersistentCollectionChangeData persistentCollectionChangeData,
|
||||
Object revision) {
|
||||
session.save( persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData() );
|
||||
session.persist( persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData() );
|
||||
sessionCacheCleaner.scheduleAuditDataRemoval( session, persistentCollectionChangeData.getData() );
|
||||
}
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
|
|||
final String auditedEntityName = configuration.getAuditEntityName( entityName );
|
||||
|
||||
// Save the audit data
|
||||
session.save( auditedEntityName, data );
|
||||
session.persist( auditedEntityName, data );
|
||||
|
||||
// Update the end date of the previous row.
|
||||
//
|
||||
|
@ -271,7 +271,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
|
|||
}
|
||||
|
||||
// Save the audit data
|
||||
session.save( persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData() );
|
||||
session.persist( persistentCollectionChangeData.getEntityName(), persistentCollectionChangeData.getData() );
|
||||
sessionCacheCleaner.scheduleAuditDataRemoval( session, persistentCollectionChangeData.getData() );
|
||||
}
|
||||
|
||||
|
@ -375,7 +375,7 @@ public class ValidityAuditStrategy implements AuditStrategy {
|
|||
}
|
||||
|
||||
// Saving the previous version
|
||||
session.save( auditedEntityName, previousData );
|
||||
session.persist( auditedEntityName, previousData );
|
||||
sessionCacheCleaner.scheduleAuditDataRemoval( session, previousData );
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -68,7 +68,6 @@ final class StaticClassLists {
|
|||
org.hibernate.event.spi.LoadEventListener[].class,
|
||||
org.hibernate.event.spi.ResolveNaturalIdEventListener[].class,
|
||||
org.hibernate.event.spi.InitializeCollectionEventListener[].class,
|
||||
org.hibernate.event.spi.SaveOrUpdateEventListener[].class,
|
||||
org.hibernate.event.spi.PersistEventListener[].class,
|
||||
org.hibernate.event.spi.MergeEventListener[].class,
|
||||
org.hibernate.event.spi.DeleteEventListener[].class,
|
||||
|
|
Loading…
Reference in New Issue