introduce Contexts for the other cascading operations that need them
and typesafety, finally!
This commit is contained in:
parent
7570d15291
commit
1b0862babd
|
@ -8,7 +8,6 @@ package org.hibernate.engine.internal;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -21,6 +20,7 @@ import org.hibernate.engine.spi.CollectionEntry;
|
|||
import org.hibernate.engine.spi.EntityEntry;
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.Status;
|
||||
import org.hibernate.event.spi.DeleteContext;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
@ -56,8 +56,8 @@ public final class Cascade {
|
|||
* @param persister The parent's entity persister
|
||||
* @param parent The parent reference.
|
||||
*/
|
||||
public static void cascade(
|
||||
final CascadingAction action, final CascadePoint cascadePoint,
|
||||
public static <T> void cascade(
|
||||
final CascadingAction<T> action, final CascadePoint cascadePoint,
|
||||
final EventSource eventSource, final EntityPersister persister, final Object parent)
|
||||
throws HibernateException {
|
||||
cascade( action, cascadePoint, eventSource, persister, parent, null );
|
||||
|
@ -72,13 +72,13 @@ public final class Cascade {
|
|||
* @param anything Anything ;) Typically some form of cascade-local cache
|
||||
* which is specific to each CascadingAction type
|
||||
*/
|
||||
public static void cascade(
|
||||
final CascadingAction action,
|
||||
public static <T> void cascade(
|
||||
final CascadingAction<T> action,
|
||||
final CascadePoint cascadePoint,
|
||||
final EventSource eventSource,
|
||||
final EntityPersister persister,
|
||||
final Object parent,
|
||||
final Object anything) throws HibernateException {
|
||||
final T anything) throws HibernateException {
|
||||
|
||||
if ( persister.hasCascades() || action.requiresNoCascadeChecking() ) { // performance opt
|
||||
final boolean traceEnabled = LOG.isTraceEnabled();
|
||||
|
@ -106,7 +106,7 @@ public final class Cascade {
|
|||
// Cascade to an uninitialized, lazy value only if
|
||||
// parent is managed in the PersistenceContext.
|
||||
// If parent is a detached entity being merged,
|
||||
// then parent will not be in the PersistencContext
|
||||
// then parent will not be in the PersistenceContext
|
||||
// (so lazy attributes must not be initialized).
|
||||
if ( persistenceContext.getEntry( parent ) == null ) {
|
||||
// parent was not in the PersistenceContext
|
||||
|
@ -199,8 +199,8 @@ public final class Cascade {
|
|||
/**
|
||||
* Cascade an action to the child or children
|
||||
*/
|
||||
private static void cascadeProperty(
|
||||
final CascadingAction action,
|
||||
private static <T> void cascadeProperty(
|
||||
final CascadingAction<T> action,
|
||||
final CascadePoint cascadePoint,
|
||||
final EventSource eventSource,
|
||||
List<String> componentPath,
|
||||
|
@ -209,7 +209,7 @@ public final class Cascade {
|
|||
final Type type,
|
||||
final CascadeStyle style,
|
||||
final String propertyName,
|
||||
final Object anything,
|
||||
final T anything,
|
||||
final boolean isCascadeDeleteEnabled) throws HibernateException {
|
||||
|
||||
if ( child != null ) {
|
||||
|
@ -265,8 +265,8 @@ public final class Cascade {
|
|||
isCascadeDeleteEnabled );
|
||||
}
|
||||
|
||||
private static void cascadeLogicalOneToOneOrphanRemoval(
|
||||
final CascadingAction action,
|
||||
private static <T> void cascadeLogicalOneToOneOrphanRemoval(
|
||||
final CascadingAction<T> action,
|
||||
final EventSource eventSource,
|
||||
final List<String> componentPath,
|
||||
final Object parent,
|
||||
|
@ -355,7 +355,7 @@ public final class Cascade {
|
|||
}
|
||||
else {
|
||||
// Else, we must delete after the updates.
|
||||
eventSource.delete( entityName, loadedValue, isCascadeDeleteEnabled, new HashSet<>() );
|
||||
eventSource.delete( entityName, loadedValue, isCascadeDeleteEnabled, DeleteContext.create() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,15 +380,15 @@ public final class Cascade {
|
|||
return associationType.getForeignKeyDirection().cascadeNow( cascadePoint );
|
||||
}
|
||||
|
||||
private static void cascadeComponent(
|
||||
final CascadingAction action,
|
||||
private static <T> void cascadeComponent(
|
||||
final CascadingAction<T> action,
|
||||
final CascadePoint cascadePoint,
|
||||
final EventSource eventSource,
|
||||
final List<String> componentPath,
|
||||
final Object parent,
|
||||
final Object child,
|
||||
final CompositeType componentType,
|
||||
final Object anything) {
|
||||
final T anything) {
|
||||
|
||||
Object[] children = null;
|
||||
final Type[] types = componentType.getSubtypes();
|
||||
|
@ -418,8 +418,8 @@ public final class Cascade {
|
|||
}
|
||||
}
|
||||
|
||||
private static void cascadeAssociation(
|
||||
final CascadingAction action,
|
||||
private static <T> void cascadeAssociation(
|
||||
final CascadingAction<T> action,
|
||||
final CascadePoint cascadePoint,
|
||||
final EventSource eventSource,
|
||||
final List<String> componentPath,
|
||||
|
@ -427,7 +427,7 @@ public final class Cascade {
|
|||
final Object child,
|
||||
final Type type,
|
||||
final CascadeStyle style,
|
||||
final Object anything,
|
||||
final T anything,
|
||||
final boolean isCascadeDeleteEnabled) {
|
||||
if ( type.isEntityType() || type.isAnyType() ) {
|
||||
cascadeToOne( action, eventSource, parent, child, type, style, anything, isCascadeDeleteEnabled );
|
||||
|
@ -450,15 +450,15 @@ public final class Cascade {
|
|||
/**
|
||||
* Cascade an action to a collection
|
||||
*/
|
||||
private static void cascadeCollection(
|
||||
final CascadingAction action,
|
||||
private static <T> void cascadeCollection(
|
||||
final CascadingAction<T> action,
|
||||
final CascadePoint cascadePoint,
|
||||
final EventSource eventSource,
|
||||
final List<String> componentPath,
|
||||
final Object parent,
|
||||
final Object child,
|
||||
final CascadeStyle style,
|
||||
final Object anything,
|
||||
final T anything,
|
||||
final CollectionType type) {
|
||||
final CollectionPersister persister = eventSource.getFactory()
|
||||
.getRuntimeMetamodels()
|
||||
|
@ -492,14 +492,14 @@ public final class Cascade {
|
|||
/**
|
||||
* Cascade an action to a to-one association or any type
|
||||
*/
|
||||
private static void cascadeToOne(
|
||||
final CascadingAction action,
|
||||
private static <T> void cascadeToOne(
|
||||
final CascadingAction<T> action,
|
||||
final EventSource eventSource,
|
||||
final Object parent,
|
||||
final Object child,
|
||||
final Type type,
|
||||
final CascadeStyle style,
|
||||
final Object anything,
|
||||
final T anything,
|
||||
final boolean isCascadeDeleteEnabled) {
|
||||
final String entityName = type.isEntityType()
|
||||
? ( (EntityType) type ).getAssociatedEntityName()
|
||||
|
@ -520,8 +520,8 @@ public final class Cascade {
|
|||
/**
|
||||
* Cascade to the collection elements
|
||||
*/
|
||||
private static void cascadeCollectionElements(
|
||||
final CascadingAction action,
|
||||
private static <T> void cascadeCollectionElements(
|
||||
final CascadingAction<T> action,
|
||||
final CascadePoint cascadePoint,
|
||||
final EventSource eventSource,
|
||||
final List<String> componentPath,
|
||||
|
@ -530,9 +530,10 @@ public final class Cascade {
|
|||
final CollectionType collectionType,
|
||||
final CascadeStyle style,
|
||||
final Type elemType,
|
||||
final Object anything,
|
||||
final T anything,
|
||||
final boolean isCascadeDeleteEnabled) throws HibernateException {
|
||||
final boolean reallyDoCascade = style.reallyDoCascade( action ) && child != CollectionType.UNFETCHED_COLLECTION;
|
||||
final boolean reallyDoCascade = style.reallyDoCascade( action )
|
||||
&& child != CollectionType.UNFETCHED_COLLECTION;
|
||||
|
||||
if ( reallyDoCascade ) {
|
||||
final boolean traceEnabled = LOG.isTraceEnabled();
|
||||
|
@ -605,7 +606,7 @@ public final class Cascade {
|
|||
for ( Object orphan : orphans ) {
|
||||
if ( orphan != null ) {
|
||||
LOG.tracev( "Deleting orphaned entity instance: {0}", entityName );
|
||||
eventSource.delete( entityName, orphan, false, new HashSet<>() );
|
||||
eventSource.delete( entityName, orphan, false, DeleteContext.create() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.hibernate.type.Type;
|
|||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface CascadingAction {
|
||||
public interface CascadingAction<T> {
|
||||
|
||||
/**
|
||||
* Cascade the action to the child object.
|
||||
|
@ -36,7 +36,7 @@ public interface CascadingAction {
|
|||
EventSource session,
|
||||
Object child,
|
||||
String entityName,
|
||||
Object anything,
|
||||
T anything,
|
||||
boolean isCascadeDeleteEnabled) throws HibernateException;
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
package org.hibernate.engine.spi;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
|
@ -17,8 +15,11 @@ import org.hibernate.ReplicationMode;
|
|||
import org.hibernate.TransientPropertyValueException;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.internal.ForeignKeys;
|
||||
import org.hibernate.event.spi.DeleteContext;
|
||||
import org.hibernate.event.spi.MergeContext;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.event.spi.PersistContext;
|
||||
import org.hibernate.event.spi.RefreshContext;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
@ -46,16 +47,16 @@ public class CascadingActions {
|
|||
/**
|
||||
* @see org.hibernate.Session#delete(Object)
|
||||
*/
|
||||
public static final CascadingAction DELETE = new BaseCascadingAction() {
|
||||
public static final CascadingAction<DeleteContext> DELETE = new BaseCascadingAction<>() {
|
||||
@Override
|
||||
public void cascade(
|
||||
EventSource session,
|
||||
Object child,
|
||||
String entityName,
|
||||
Object anything,
|
||||
DeleteContext context,
|
||||
boolean isCascadeDeleteEnabled) {
|
||||
LOG.tracev( "Cascading to delete: {0}", entityName );
|
||||
session.delete( entityName, child, isCascadeDeleteEnabled, (Set<?>) anything );
|
||||
session.delete( entityName, child, isCascadeDeleteEnabled, context );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,19 +83,18 @@ public class CascadingActions {
|
|||
/**
|
||||
* @see org.hibernate.Session#lock(Object, LockMode)
|
||||
*/
|
||||
public static final CascadingAction LOCK = new BaseCascadingAction() {
|
||||
public static final CascadingAction<LockOptions> LOCK = new BaseCascadingAction<>() {
|
||||
@Override
|
||||
public void cascade(
|
||||
EventSource session,
|
||||
Object child,
|
||||
String entityName,
|
||||
Object anything,
|
||||
LockOptions lockOptions,
|
||||
boolean isCascadeDeleteEnabled) {
|
||||
LOG.tracev( "Cascading to lock: {0}", entityName );
|
||||
LockMode lockMode = LockMode.NONE;
|
||||
LockOptions lr = new LockOptions();
|
||||
if ( anything instanceof LockOptions ) {
|
||||
LockOptions lockOptions = (LockOptions) anything;
|
||||
if ( lockOptions != null ) {
|
||||
lr.setTimeOut( lockOptions.getTimeOut() );
|
||||
lr.setScope( lockOptions.getScope() );
|
||||
lr.setFollowOnLocking( lockOptions.getFollowOnLocking() );
|
||||
|
@ -130,17 +130,17 @@ public class CascadingActions {
|
|||
/**
|
||||
* @see org.hibernate.Session#refresh(Object)
|
||||
*/
|
||||
public static final CascadingAction REFRESH = new BaseCascadingAction() {
|
||||
public static final CascadingAction<RefreshContext> REFRESH = new BaseCascadingAction<>() {
|
||||
@Override
|
||||
public void cascade(
|
||||
EventSource session,
|
||||
Object child,
|
||||
String entityName,
|
||||
Object anything,
|
||||
RefreshContext context,
|
||||
boolean isCascadeDeleteEnabled)
|
||||
throws HibernateException {
|
||||
LOG.tracev( "Cascading to refresh: {0}", entityName );
|
||||
session.refresh( entityName, child, (Map<?,?>) anything );
|
||||
session.refresh( entityName, child, context );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -166,13 +166,13 @@ public class CascadingActions {
|
|||
/**
|
||||
* @see org.hibernate.Session#evict(Object)
|
||||
*/
|
||||
public static final CascadingAction EVICT = new BaseCascadingAction() {
|
||||
public static final CascadingAction<Void> EVICT = new BaseCascadingAction<>() {
|
||||
@Override
|
||||
public void cascade(
|
||||
EventSource session,
|
||||
Object child,
|
||||
String entityName,
|
||||
Object anything,
|
||||
Void nothing,
|
||||
boolean isCascadeDeleteEnabled)
|
||||
throws HibernateException {
|
||||
LOG.tracev( "Cascading to evict: {0}", entityName );
|
||||
|
@ -207,13 +207,13 @@ public class CascadingActions {
|
|||
/**
|
||||
* @see org.hibernate.Session#saveOrUpdate(Object)
|
||||
*/
|
||||
public static final CascadingAction SAVE_UPDATE = new BaseCascadingAction() {
|
||||
public static final CascadingAction<PersistContext> SAVE_UPDATE = new BaseCascadingAction<>() {
|
||||
@Override
|
||||
public void cascade(
|
||||
EventSource session,
|
||||
Object child,
|
||||
String entityName,
|
||||
Object anything,
|
||||
PersistContext nothing,
|
||||
boolean isCascadeDeleteEnabled)
|
||||
throws HibernateException {
|
||||
LOG.tracev( "Cascading to save or update: {0}", entityName );
|
||||
|
@ -249,17 +249,17 @@ public class CascadingActions {
|
|||
/**
|
||||
* @see org.hibernate.Session#merge(Object)
|
||||
*/
|
||||
public static final CascadingAction MERGE = new BaseCascadingAction() {
|
||||
public static final CascadingAction<MergeContext> MERGE = new BaseCascadingAction<>() {
|
||||
@Override
|
||||
public void cascade(
|
||||
EventSource session,
|
||||
Object child,
|
||||
String entityName,
|
||||
Object anything,
|
||||
MergeContext context,
|
||||
boolean isCascadeDeleteEnabled)
|
||||
throws HibernateException {
|
||||
LOG.tracev( "Cascading to merge: {0}", entityName );
|
||||
session.merge( entityName, child, (MergeContext) anything );
|
||||
session.merge( entityName, child, context );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -286,17 +286,17 @@ public class CascadingActions {
|
|||
/**
|
||||
* @see org.hibernate.Session#persist(Object)
|
||||
*/
|
||||
public static final CascadingAction PERSIST = new BaseCascadingAction() {
|
||||
public static final CascadingAction<PersistContext> PERSIST = new BaseCascadingAction<>() {
|
||||
@Override
|
||||
public void cascade(
|
||||
EventSource session,
|
||||
Object child,
|
||||
String entityName,
|
||||
Object anything,
|
||||
PersistContext context,
|
||||
boolean isCascadeDeleteEnabled)
|
||||
throws HibernateException {
|
||||
LOG.tracev( "Cascading to persist: {0}", entityName );
|
||||
session.persist( entityName, child, (Map<?,?>) anything );
|
||||
session.persist( entityName, child, context );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -329,17 +329,17 @@ public class CascadingActions {
|
|||
*
|
||||
* @see org.hibernate.Session#persist(Object)
|
||||
*/
|
||||
public static final CascadingAction PERSIST_ON_FLUSH = new BaseCascadingAction() {
|
||||
public static final CascadingAction<PersistContext> PERSIST_ON_FLUSH = new BaseCascadingAction<>() {
|
||||
@Override
|
||||
public void cascade(
|
||||
EventSource session,
|
||||
Object child,
|
||||
String entityName,
|
||||
Object anything,
|
||||
PersistContext anything,
|
||||
boolean isCascadeDeleteEnabled)
|
||||
throws HibernateException {
|
||||
LOG.tracev( "Cascading to persist on flush: {0}", entityName );
|
||||
session.persistOnFlush( entityName, child, (Map<?,?>) anything );
|
||||
session.persistOnFlush( entityName, child, anything );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -373,8 +373,9 @@ public class CascadingActions {
|
|||
if ( child != null
|
||||
&& !isInManagedState( child, session )
|
||||
&& !(child instanceof HibernateProxy) ) { //a proxy cannot be transient and it breaks ForeignKeys.isTransient
|
||||
final String childEntityName = ((EntityType) propertyType).getAssociatedEntityName(session.getFactory());
|
||||
if (ForeignKeys.isTransient(childEntityName, child, null, session)) {
|
||||
final String childEntityName =
|
||||
((EntityType) propertyType).getAssociatedEntityName( session.getFactory() );
|
||||
if ( ForeignKeys.isTransient(childEntityName, child, null, session) ) {
|
||||
String parentEntityName = persister.getEntityName();
|
||||
String propertyName = persister.getPropertyNames()[propertyIndex];
|
||||
throw new TransientPropertyValueException(
|
||||
|
@ -412,17 +413,17 @@ public class CascadingActions {
|
|||
/**
|
||||
* @see org.hibernate.Session#replicate
|
||||
*/
|
||||
public static final CascadingAction REPLICATE = new BaseCascadingAction() {
|
||||
public static final CascadingAction<ReplicationMode> REPLICATE = new BaseCascadingAction<>() {
|
||||
@Override
|
||||
public void cascade(
|
||||
EventSource session,
|
||||
Object child,
|
||||
String entityName,
|
||||
Object anything,
|
||||
ReplicationMode anything,
|
||||
boolean isCascadeDeleteEnabled)
|
||||
throws HibernateException {
|
||||
LOG.tracev( "Cascading to replicate: {0}", entityName );
|
||||
session.replicate( entityName, child, (ReplicationMode) anything );
|
||||
session.replicate( entityName, child, anything );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -445,7 +446,7 @@ public class CascadingActions {
|
|||
}
|
||||
};
|
||||
|
||||
public abstract static class BaseCascadingAction implements CascadingAction {
|
||||
public abstract static class BaseCascadingAction<T> implements CascadingAction<T> {
|
||||
@Override
|
||||
public boolean requiresNoCascadeChecking() {
|
||||
return false;
|
||||
|
|
|
@ -37,7 +37,10 @@ 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.DeleteContext;
|
||||
import org.hibernate.event.spi.MergeContext;
|
||||
import org.hibernate.event.spi.PersistContext;
|
||||
import org.hibernate.event.spi.RefreshContext;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.jdbc.ReturningWork;
|
||||
import org.hibernate.jdbc.Work;
|
||||
|
@ -1102,22 +1105,22 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void persist(String entityName, Object object, Map createdAlready) throws HibernateException {
|
||||
public void persist(String entityName, Object object, PersistContext createdAlready) throws HibernateException {
|
||||
delegate.persist( entityName, object, createdAlready );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void persistOnFlush(String entityName, Object object, Map copiedAlready) {
|
||||
public void persistOnFlush(String entityName, Object object, PersistContext copiedAlready) {
|
||||
delegate.persistOnFlush( entityName, object, copiedAlready );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(String entityName, Object object, Map refreshedAlready) throws HibernateException {
|
||||
public void refresh(String entityName, Object object, RefreshContext refreshedAlready) throws HibernateException {
|
||||
delegate.refresh( entityName, object, refreshedAlready );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String entityName, Object child, boolean isCascadeDeleteEnabled, Set transientEntities) {
|
||||
public void delete(String entityName, Object child, boolean isCascadeDeleteEnabled, DeleteContext transientEntities) {
|
||||
delegate.delete( entityName, child, isCascadeDeleteEnabled, transientEntities );
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,10 @@ import java.util.Set;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.event.spi.DeleteContext;
|
||||
import org.hibernate.event.spi.MergeContext;
|
||||
import org.hibernate.event.spi.PersistContext;
|
||||
import org.hibernate.event.spi.RefreshContext;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
|
||||
|
@ -84,25 +87,25 @@ public interface SessionImplementor extends Session, SharedSessionContractImplem
|
|||
* @deprecated OperationalContext should cover this overload I believe
|
||||
*/
|
||||
@Deprecated
|
||||
void persist(String entityName, Object object, Map createdAlready) throws HibernateException;
|
||||
void persist(String entityName, Object object, PersistContext createdAlready) throws HibernateException;
|
||||
|
||||
/**
|
||||
* @deprecated OperationalContext should cover this overload I believe
|
||||
*/
|
||||
@Deprecated
|
||||
void persistOnFlush(String entityName, Object object, Map copiedAlready);
|
||||
void persistOnFlush(String entityName, Object object, PersistContext copiedAlready);
|
||||
|
||||
/**
|
||||
* @deprecated OperationalContext should cover this overload I believe
|
||||
*/
|
||||
@Deprecated
|
||||
void refresh(String entityName, Object object, Map refreshedAlready) throws HibernateException;
|
||||
void refresh(String entityName, Object object, RefreshContext refreshedAlready) throws HibernateException;
|
||||
|
||||
/**
|
||||
* @deprecated OperationalContext should cover this overload I believe
|
||||
*/
|
||||
@Deprecated
|
||||
void delete(String entityName, Object child, boolean isCascadeDeleteEnabled, Set transientEntities);
|
||||
void delete(String entityName, Object child, boolean isCascadeDeleteEnabled, DeleteContext transientEntities);
|
||||
|
||||
/**
|
||||
* @deprecated OperationalContext should cover this overload I believe
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.event.internal;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -33,6 +32,7 @@ import org.hibernate.event.spi.EventSource;
|
|||
import org.hibernate.event.spi.FlushEntityEvent;
|
||||
import org.hibernate.event.spi.FlushEntityEventListener;
|
||||
import org.hibernate.event.spi.FlushEvent;
|
||||
import org.hibernate.event.spi.PersistContext;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.EntityPrinter;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
@ -135,19 +135,19 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
|
||||
LOG.debug( "Processing flush-time cascades" );
|
||||
|
||||
final Object anything = getAnything();
|
||||
final PersistContext context = getContext();
|
||||
//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 = me.getValue();
|
||||
Status status = entry.getStatus();
|
||||
if ( status == Status.MANAGED || status == Status.SAVING || status == Status.READ_ONLY ) {
|
||||
cascadeOnFlush( session, entry.getPersister(), me.getKey(), anything );
|
||||
cascadeOnFlush( session, entry.getPersister(), me.getKey(), context );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cascadeOnFlush(EventSource session, EntityPersister persister, Object object, Object anything)
|
||||
private void cascadeOnFlush(EventSource session, EntityPersister persister, Object object, PersistContext anything)
|
||||
throws HibernateException {
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
persistenceContext.incrementCascadeLevel();
|
||||
|
@ -159,11 +159,11 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
}
|
||||
}
|
||||
|
||||
protected Object getAnything() {
|
||||
return jpaBootstrap ? new IdentityHashMap<>(10) : null;
|
||||
protected PersistContext getContext() {
|
||||
return jpaBootstrap ? PersistContext.create() : null;
|
||||
}
|
||||
|
||||
protected CascadingAction getCascadingAction() {
|
||||
protected CascadingAction<PersistContext> getCascadingAction() {
|
||||
return jpaBootstrap ? CascadingActions.PERSIST_ON_FLUSH : CascadingActions.SAVE_UPDATE;
|
||||
}
|
||||
|
||||
|
@ -177,9 +177,7 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
|
|||
// and reset reached, doupdate, etc.
|
||||
|
||||
LOG.debug( "Dirty checking collections" );
|
||||
persistenceContext.forEachCollectionEntry( (pc,ce) -> {
|
||||
ce.preFlush( pc );
|
||||
}, true );
|
||||
persistenceContext.forEachCollectionEntry( (pc,ce) -> ce.preFlush( pc ), true );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,7 +42,7 @@ import org.hibernate.type.TypeHelper;
|
|||
*
|
||||
* @author Steve Ebersole.
|
||||
*/
|
||||
public abstract class AbstractSaveEventListener
|
||||
public abstract class AbstractSaveEventListener<C>
|
||||
extends AbstractReassociateEventListener
|
||||
implements CallbackRegistryConsumer {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractSaveEventListener.class );
|
||||
|
@ -59,7 +59,7 @@ public abstract class AbstractSaveEventListener
|
|||
* @param entity The entity to be saved.
|
||||
* @param requestedId The id to which to associate the entity.
|
||||
* @param entityName The name of the entity being saved.
|
||||
* @param anything Generally cascade-specific information.
|
||||
* @param context Generally cascade-specific information.
|
||||
* @param source The session which is the source of this save event.
|
||||
*
|
||||
* @return The id used to save the entity.
|
||||
|
@ -68,7 +68,7 @@ public abstract class AbstractSaveEventListener
|
|||
Object entity,
|
||||
Object requestedId,
|
||||
String entityName,
|
||||
Object anything,
|
||||
C context,
|
||||
EventSource source) {
|
||||
callbackRegistry.preCreate( entity );
|
||||
|
||||
|
@ -77,7 +77,7 @@ public abstract class AbstractSaveEventListener
|
|||
requestedId,
|
||||
source.getEntityPersister( entityName, entity ),
|
||||
false,
|
||||
anything,
|
||||
context,
|
||||
source,
|
||||
true
|
||||
);
|
||||
|
@ -88,7 +88,7 @@ public abstract class AbstractSaveEventListener
|
|||
*
|
||||
* @param entity The entity to be saved
|
||||
* @param entityName The entity-name for the entity to be saved
|
||||
* @param anything Generally cascade-specific information.
|
||||
* @param context Generally cascade-specific information.
|
||||
* @param source The session which is the source of this save event.
|
||||
* @param requiresImmediateIdAccess does the event context require
|
||||
* access to the identifier immediately after execution of this method (if
|
||||
|
@ -101,7 +101,7 @@ public abstract class AbstractSaveEventListener
|
|||
protected Object saveWithGeneratedId(
|
||||
Object entity,
|
||||
String entityName,
|
||||
Object anything,
|
||||
C context,
|
||||
EventSource source,
|
||||
boolean requiresImmediateIdAccess) {
|
||||
callbackRegistry.preCreate( entity );
|
||||
|
@ -119,7 +119,7 @@ public abstract class AbstractSaveEventListener
|
|||
return source.getIdentifier( entity );
|
||||
}
|
||||
else if ( generatedId == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) {
|
||||
return performSave( entity, null, persister, true, anything, source, requiresImmediateIdAccess );
|
||||
return performSave( entity, null, persister, true, context, source, requiresImmediateIdAccess );
|
||||
}
|
||||
else {
|
||||
// TODO: define toString()s for generators
|
||||
|
@ -131,7 +131,7 @@ public abstract class AbstractSaveEventListener
|
|||
);
|
||||
}
|
||||
|
||||
return performSave( entity, generatedId, persister, false, anything, source, true );
|
||||
return performSave( entity, generatedId, persister, false, context, source, true );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ public abstract class AbstractSaveEventListener
|
|||
* @param id The id by which to save the entity.
|
||||
* @param persister The entity's persister instance.
|
||||
* @param useIdentityColumn Is an identity column being used?
|
||||
* @param anything Generally cascade-specific information.
|
||||
* @param context Generally cascade-specific information.
|
||||
* @param source The session from which the event originated.
|
||||
* @param requiresImmediateIdAccess does the event context require
|
||||
* access to the identifier immediately after execution of this method (if
|
||||
|
@ -158,7 +158,7 @@ public abstract class AbstractSaveEventListener
|
|||
Object id,
|
||||
EntityPersister persister,
|
||||
boolean useIdentityColumn,
|
||||
Object anything,
|
||||
C context,
|
||||
EventSource source,
|
||||
boolean requiresImmediateIdAccess) {
|
||||
|
||||
|
@ -194,7 +194,7 @@ public abstract class AbstractSaveEventListener
|
|||
key,
|
||||
persister,
|
||||
useIdentityColumn,
|
||||
anything,
|
||||
context,
|
||||
source,
|
||||
requiresImmediateIdAccess
|
||||
);
|
||||
|
@ -221,7 +221,7 @@ public abstract class AbstractSaveEventListener
|
|||
* @param key The id to be used for saving the entity (or null, in the case of identity columns)
|
||||
* @param persister The entity's persister instance.
|
||||
* @param useIdentityColumn Should an identity column be used for id generation?
|
||||
* @param anything Generally cascade-specific information.
|
||||
* @param context Generally cascade-specific information.
|
||||
* @param source The session which is the source of the current event.
|
||||
* @param requiresImmediateIdAccess Is access to the identifier required immediately
|
||||
* after the completion of the save? persist(), for example, does not require this...
|
||||
|
@ -234,7 +234,7 @@ public abstract class AbstractSaveEventListener
|
|||
EntityKey key,
|
||||
EntityPersister persister,
|
||||
boolean useIdentityColumn,
|
||||
Object anything,
|
||||
C context,
|
||||
EventSource source,
|
||||
boolean requiresImmediateIdAccess) {
|
||||
|
||||
|
@ -260,9 +260,9 @@ public abstract class AbstractSaveEventListener
|
|||
false
|
||||
);
|
||||
|
||||
cascadeBeforeSave( source, persister, entity, anything );
|
||||
cascadeBeforeSave( source, persister, entity, context );
|
||||
|
||||
Object[] values = persister.getPropertyValuesToInsert( entity, getMergeMap( anything ), source );
|
||||
Object[] values = persister.getPropertyValuesToInsert( entity, getMergeMap( context ), source );
|
||||
Type[] types = persister.getPropertyTypes();
|
||||
|
||||
boolean substitute = substituteValuesIfNecessary( entity, id, values, persister, source );
|
||||
|
@ -295,7 +295,7 @@ public abstract class AbstractSaveEventListener
|
|||
|
||||
// postpone initializing id in case the insert has non-nullable transient dependencies
|
||||
// that are not resolved until cascadeAfterSave() is executed
|
||||
cascadeAfterSave( source, persister, entity, anything );
|
||||
cascadeAfterSave( source, persister, entity, context );
|
||||
if ( useIdentityColumn && insert.isEarlyInsert() ) {
|
||||
if ( !(insert instanceof EntityIdentityInsertAction) ) {
|
||||
throw new IllegalStateException(
|
||||
|
@ -355,7 +355,7 @@ public abstract class AbstractSaveEventListener
|
|||
}
|
||||
}
|
||||
|
||||
protected Map<Object,Object> getMergeMap(Object anything) {
|
||||
protected Map<Object,Object> getMergeMap(C anything) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -427,13 +427,13 @@ public abstract class AbstractSaveEventListener
|
|||
* @param source The session from which the save event originated.
|
||||
* @param persister The entity's persister instance.
|
||||
* @param entity The entity to be saved.
|
||||
* @param anything Generally cascade-specific data
|
||||
* @param context Generally cascade-specific data
|
||||
*/
|
||||
protected void cascadeBeforeSave(
|
||||
EventSource source,
|
||||
EntityPersister persister,
|
||||
Object entity,
|
||||
Object anything) {
|
||||
C context) {
|
||||
|
||||
// cascade-save to many-to-one BEFORE the parent is saved
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
|
@ -445,7 +445,7 @@ public abstract class AbstractSaveEventListener
|
|||
source,
|
||||
persister,
|
||||
entity,
|
||||
anything
|
||||
context
|
||||
);
|
||||
}
|
||||
finally {
|
||||
|
@ -459,13 +459,13 @@ public abstract class AbstractSaveEventListener
|
|||
* @param source The session from which the event originated.
|
||||
* @param persister The entity's persister instance.
|
||||
* @param entity The entity being saved.
|
||||
* @param anything Generally cascade-specific data
|
||||
* @param context Generally cascade-specific data
|
||||
*/
|
||||
protected void cascadeAfterSave(
|
||||
EventSource source,
|
||||
EntityPersister persister,
|
||||
Object entity,
|
||||
Object anything) {
|
||||
C context) {
|
||||
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
// cascade-save to collections AFTER the collection owner was saved
|
||||
|
@ -477,7 +477,7 @@ public abstract class AbstractSaveEventListener
|
|||
source,
|
||||
persister,
|
||||
entity,
|
||||
anything
|
||||
context
|
||||
);
|
||||
}
|
||||
finally {
|
||||
|
@ -485,6 +485,6 @@ public abstract class AbstractSaveEventListener
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract CascadingAction getCascadeAction();
|
||||
protected abstract CascadingAction<C> getCascadeAction();
|
||||
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.event.internal;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
|
@ -26,12 +24,12 @@ import org.hibernate.engine.spi.EntityKey;
|
|||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.Status;
|
||||
import org.hibernate.event.service.spi.JpaBootstrapSensitive;
|
||||
import org.hibernate.event.spi.DeleteContext;
|
||||
import org.hibernate.event.spi.DeleteEvent;
|
||||
import org.hibernate.event.spi.DeleteEventListener;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.collections.IdentitySet;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistry;
|
||||
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
@ -68,7 +66,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
*
|
||||
*/
|
||||
public void onDelete(DeleteEvent event) throws HibernateException {
|
||||
onDelete( event, new IdentitySet<>() );
|
||||
onDelete( event, DeleteContext.create() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,7 +76,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
* @param transientEntities The cache of entities already deleted
|
||||
*
|
||||
*/
|
||||
public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {
|
||||
public void onDelete(DeleteEvent event, DeleteContext transientEntities) throws HibernateException {
|
||||
|
||||
final EventSource source = event.getSession();
|
||||
|
||||
|
@ -208,13 +206,12 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
Object entity,
|
||||
boolean cascadeDeleteEnabled,
|
||||
EntityPersister persister,
|
||||
Set transientEntities) {
|
||||
DeleteContext transientEntities) {
|
||||
LOG.handlingTransientEntity();
|
||||
if ( transientEntities.contains( entity ) ) {
|
||||
if ( !transientEntities.add( entity ) ) {
|
||||
LOG.trace( "Already handled transient entity; skipping" );
|
||||
return;
|
||||
}
|
||||
transientEntities.add( entity );
|
||||
cascadeBeforeDelete( session, persister, entity, null, transientEntities );
|
||||
cascadeAfterDelete( session, persister, entity, transientEntities );
|
||||
}
|
||||
|
@ -238,7 +235,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
final boolean isCascadeDeleteEnabled,
|
||||
final boolean isOrphanRemovalBeforeUpdates,
|
||||
final EntityPersister persister,
|
||||
final Set transientEntities) {
|
||||
final DeleteContext transientEntities) {
|
||||
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
|
@ -342,7 +339,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
EntityPersister persister,
|
||||
Object entity,
|
||||
EntityEntry entityEntry,
|
||||
Set transientEntities) throws HibernateException {
|
||||
DeleteContext transientEntities) throws HibernateException {
|
||||
|
||||
CacheMode cacheMode = session.getCacheMode();
|
||||
session.setCacheMode( CacheMode.GET );
|
||||
|
@ -369,7 +366,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
EventSource session,
|
||||
EntityPersister persister,
|
||||
Object entity,
|
||||
Set transientEntities) throws HibernateException {
|
||||
DeleteContext transientEntities) throws HibernateException {
|
||||
|
||||
CacheMode cacheMode = session.getCacheMode();
|
||||
session.setCacheMode( CacheMode.GET );
|
||||
|
|
|
@ -48,12 +48,14 @@ import org.hibernate.type.TypeHelper;
|
|||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class DefaultMergeEventListener extends AbstractSaveEventListener implements MergeEventListener {
|
||||
public class DefaultMergeEventListener
|
||||
extends AbstractSaveEventListener<MergeContext>
|
||||
implements MergeEventListener {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultMergeEventListener.class );
|
||||
|
||||
@Override
|
||||
protected Map<Object,Object> getMergeMap(Object anything) {
|
||||
return ( (MergeContext) anything ).invertMap();
|
||||
protected Map<Object,Object> getMergeMap(MergeContext context) {
|
||||
return context.invertMap();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,14 +128,14 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
|||
entity = original;
|
||||
}
|
||||
|
||||
if ( ((MergeContext) copiedAlready).containsKey( entity ) && ((MergeContext) copiedAlready).isOperatedOn( entity ) ) {
|
||||
if ( copiedAlready.containsKey( entity ) && copiedAlready.isOperatedOn( entity ) ) {
|
||||
LOG.trace( "Already in merge process" );
|
||||
event.setResult( entity );
|
||||
}
|
||||
else {
|
||||
if ( ((MergeContext) copiedAlready).containsKey( entity ) ) {
|
||||
if ( copiedAlready.containsKey( entity ) ) {
|
||||
LOG.trace( "Already in copyCache; setting in merge process" );
|
||||
((MergeContext) copiedAlready).setOperatedOn( entity, true );
|
||||
copiedAlready.setOperatedOn( entity, true );
|
||||
}
|
||||
event.setEntity( entity );
|
||||
EntityState entityState = null;
|
||||
|
@ -166,13 +168,13 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
|||
|
||||
switch ( entityState ) {
|
||||
case DETACHED:
|
||||
entityIsDetached( event, (MergeContext) copiedAlready);
|
||||
entityIsDetached( event, copiedAlready);
|
||||
break;
|
||||
case TRANSIENT:
|
||||
entityIsTransient( event, (MergeContext) copiedAlready);
|
||||
entityIsTransient( event, copiedAlready);
|
||||
break;
|
||||
case PERSISTENT:
|
||||
entityIsPersistent( event, (MergeContext) copiedAlready);
|
||||
entityIsPersistent( event, copiedAlready);
|
||||
break;
|
||||
default: //DELETED
|
||||
throw new ObjectDeletedException(
|
||||
|
@ -530,7 +532,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
|||
|
||||
|
||||
@Override
|
||||
protected CascadingAction getCascadeAction() {
|
||||
protected CascadingAction<MergeContext> getCascadeAction() {
|
||||
return CascadingActions.MERGE;
|
||||
}
|
||||
|
||||
|
@ -538,7 +540,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
|||
* Cascade behavior is redefined by this subclass, disable superclass behavior
|
||||
*/
|
||||
@Override
|
||||
protected void cascadeAfterSave(EventSource source, EntityPersister persister, Object entity, Object anything)
|
||||
protected void cascadeAfterSave(EventSource source, EntityPersister persister, Object entity, MergeContext anything)
|
||||
throws HibernateException {
|
||||
}
|
||||
|
||||
|
@ -546,7 +548,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
|||
* Cascade behavior is redefined by this subclass, disable superclass behavior
|
||||
*/
|
||||
@Override
|
||||
protected void cascadeBeforeSave(EventSource source, EntityPersister persister, Object entity, Object anything)
|
||||
protected void cascadeBeforeSave(EventSource source, EntityPersister persister, Object entity, MergeContext anything)
|
||||
throws HibernateException {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.event.internal;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.ObjectDeletedException;
|
||||
import org.hibernate.PersistentObjectException;
|
||||
|
@ -18,6 +15,7 @@ import org.hibernate.engine.spi.EntityEntry;
|
|||
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.PersistEvent;
|
||||
import org.hibernate.event.spi.PersistEventListener;
|
||||
import org.hibernate.id.ForeignGenerator;
|
||||
|
@ -36,12 +34,12 @@ import org.hibernate.proxy.LazyInitializer;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class DefaultPersistEventListener
|
||||
extends AbstractSaveEventListener
|
||||
extends AbstractSaveEventListener<PersistContext>
|
||||
implements PersistEventListener, CallbackRegistryConsumer {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultPersistEventListener.class );
|
||||
|
||||
@Override
|
||||
protected CascadingAction getCascadeAction() {
|
||||
protected CascadingAction<PersistContext> getCascadeAction() {
|
||||
return CascadingActions.PERSIST;
|
||||
}
|
||||
|
||||
|
@ -52,7 +50,7 @@ public class DefaultPersistEventListener
|
|||
*
|
||||
*/
|
||||
public void onPersist(PersistEvent event) throws HibernateException {
|
||||
onPersist( event, new IdentityHashMap<>( 10 ) );
|
||||
onPersist( event, PersistContext.create() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,7 +59,7 @@ public class DefaultPersistEventListener
|
|||
* @param event The create event to be handled.
|
||||
*
|
||||
*/
|
||||
public void onPersist(PersistEvent event, Map createCache) throws HibernateException {
|
||||
public void onPersist(PersistEvent event, PersistContext createCache) throws HibernateException {
|
||||
final SessionImplementor source = event.getSession();
|
||||
final Object object = event.getObject();
|
||||
|
||||
|
@ -149,7 +147,7 @@ public class DefaultPersistEventListener
|
|||
|
||||
}
|
||||
|
||||
protected void entityIsPersistent(PersistEvent event, Map createCache) {
|
||||
protected void entityIsPersistent(PersistEvent event, PersistContext createCache) {
|
||||
LOG.trace( "Ignoring persistent instance" );
|
||||
final EventSource source = event.getSession();
|
||||
|
||||
|
@ -158,13 +156,13 @@ public class DefaultPersistEventListener
|
|||
final Object entity = source.getPersistenceContextInternal().unproxy( event.getObject() );
|
||||
final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
|
||||
|
||||
if ( createCache.put( entity, entity ) == null ) {
|
||||
if ( createCache.add( entity ) ) {
|
||||
justCascade( createCache, source, entity, persister );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void justCascade(Map createCache, EventSource source, Object entity, EntityPersister persister) {
|
||||
private void justCascade(PersistContext createCache, EventSource source, Object entity, EntityPersister persister) {
|
||||
//TODO: merge into one method!
|
||||
cascadeBeforeSave( source, persister, entity, createCache );
|
||||
cascadeAfterSave( source, persister, entity, createCache );
|
||||
|
@ -176,18 +174,18 @@ public class DefaultPersistEventListener
|
|||
* @param event The save event to be handled.
|
||||
* @param createCache The copy cache of entity instance to merge/copy instance.
|
||||
*/
|
||||
protected void entityIsTransient(PersistEvent event, Map createCache) {
|
||||
protected void entityIsTransient(PersistEvent event, PersistContext createCache) {
|
||||
LOG.trace( "Saving transient instance" );
|
||||
|
||||
final EventSource source = event.getSession();
|
||||
final Object entity = source.getPersistenceContextInternal().unproxy( event.getObject() );
|
||||
|
||||
if ( createCache.put( entity, entity ) == null ) {
|
||||
if ( createCache.add( entity ) ) {
|
||||
saveWithGeneratedId( entity, event.getEntityName(), createCache, source, false );
|
||||
}
|
||||
}
|
||||
|
||||
private void entityIsDeleted(PersistEvent event, Map createCache) {
|
||||
private void entityIsDeleted(PersistEvent event, PersistContext createCache) {
|
||||
final EventSource source = event.getSession();
|
||||
|
||||
final Object entity = source.getPersistenceContextInternal().unproxy( event.getObject() );
|
||||
|
@ -204,7 +202,7 @@ public class DefaultPersistEventListener
|
|||
);
|
||||
}
|
||||
|
||||
if ( createCache.put( entity, entity ) == null ) {
|
||||
if ( createCache.add( entity ) ) {
|
||||
justCascade( createCache, source, entity, persister );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,14 @@ package org.hibernate.event.internal;
|
|||
|
||||
import org.hibernate.engine.spi.CascadingAction;
|
||||
import org.hibernate.engine.spi.CascadingActions;
|
||||
import org.hibernate.event.spi.PersistContext;
|
||||
|
||||
/**
|
||||
* When persist is used as the cascade action, persistOnFlush should be used
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class DefaultPersistOnFlushEventListener extends DefaultPersistEventListener {
|
||||
protected CascadingAction getCascadeAction() {
|
||||
protected CascadingAction<PersistContext> getCascadeAction() {
|
||||
return CascadingActions.PERSIST_ON_FLUSH;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.event.internal;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
|
@ -26,6 +23,7 @@ import org.hibernate.engine.spi.EntityKey;
|
|||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.event.spi.RefreshContext;
|
||||
import org.hibernate.event.spi.RefreshEvent;
|
||||
import org.hibernate.event.spi.RefreshEventListener;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
|
@ -49,7 +47,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultRefreshEventListener.class );
|
||||
|
||||
public void onRefresh(RefreshEvent event) throws HibernateException {
|
||||
onRefresh( event, new IdentityHashMap<>( 10 ) );
|
||||
onRefresh( event, RefreshContext.create() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,7 +55,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
*
|
||||
* @param event The refresh event to be handled.
|
||||
*/
|
||||
public void onRefresh(RefreshEvent event, Map refreshedAlready) {
|
||||
public void onRefresh(RefreshEvent event, RefreshContext refreshedAlready) {
|
||||
|
||||
final EventSource source = event.getSession();
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
|
@ -74,7 +72,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
|
||||
final Object object = persistenceContext.unproxyAndReassociate( event.getObject() );
|
||||
|
||||
if ( refreshedAlready.containsKey( object ) ) {
|
||||
if ( !refreshedAlready.add( object ) ) {
|
||||
LOG.trace( "Already refreshed" );
|
||||
return;
|
||||
}
|
||||
|
@ -126,7 +124,6 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
}
|
||||
|
||||
// cascade the refresh prior to refreshing this entity
|
||||
refreshedAlready.put( object, object );
|
||||
Cascade.cascade(
|
||||
CascadingActions.REFRESH,
|
||||
CascadePoint.BEFORE_REFRESH,
|
||||
|
@ -224,7 +221,7 @@ public class DefaultRefreshEventListener implements RefreshEventListener {
|
|||
if ( result != null ) {
|
||||
// apply `postRefreshLockMode`, if needed
|
||||
if ( postRefreshLockMode != null ) {
|
||||
// if we get here, there was a previous entry and we need to re-set its lock-mode
|
||||
// if we get here, there was a previous entry, and we need to re-set its lock-mode
|
||||
// - however, the refresh operation actually creates a new entry, so get it
|
||||
persistenceContext.getEntry( result ).setLockMode( postRefreshLockMode );
|
||||
}
|
||||
|
|
|
@ -34,7 +34,9 @@ import org.hibernate.type.Type;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DefaultReplicateEventListener extends AbstractSaveEventListener implements ReplicateEventListener {
|
||||
public class DefaultReplicateEventListener
|
||||
extends AbstractSaveEventListener<ReplicationMode>
|
||||
implements ReplicateEventListener {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultReplicateEventListener.class );
|
||||
|
||||
/**
|
||||
|
@ -88,15 +90,14 @@ public class DefaultReplicateEventListener extends AbstractSaveEventListener imp
|
|||
);
|
||||
}
|
||||
|
||||
/// HHH-2378
|
||||
final Object realOldVersion = persister.isVersioned() ? oldVersion : null;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final BasicType<Object> versionType = (BasicType<Object>) persister.getVersionType();
|
||||
final Object realOldVersion = persister.isVersioned() ? oldVersion : null; /// HHH-2378
|
||||
boolean canReplicate = replicationMode.shouldOverwriteCurrentVersion(
|
||||
entity,
|
||||
realOldVersion,
|
||||
persister.getVersion( entity ),
|
||||
(BasicType<Object>) persister.getVersionType()
|
||||
versionType
|
||||
);
|
||||
|
||||
// if can replicate, will result in a SQL UPDATE
|
||||
|
@ -215,7 +216,7 @@ public class DefaultReplicateEventListener extends AbstractSaveEventListener imp
|
|||
}
|
||||
|
||||
@Override
|
||||
protected CascadingAction getCascadeAction() {
|
||||
protected CascadingAction<ReplicationMode> getCascadeAction() {
|
||||
return CascadingActions.REPLICATE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ 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;
|
||||
|
@ -38,7 +39,9 @@ import org.hibernate.proxy.HibernateProxy;
|
|||
* @author Steve Ebersole
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener implements SaveOrUpdateEventListener {
|
||||
public class DefaultSaveOrUpdateEventListener
|
||||
extends AbstractSaveEventListener<PersistContext>
|
||||
implements SaveOrUpdateEventListener {
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultSaveOrUpdateEventListener.class );
|
||||
|
||||
/**
|
||||
|
@ -363,7 +366,7 @@ public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener
|
|||
}
|
||||
|
||||
@Override
|
||||
protected CascadingAction getCascadeAction() {
|
||||
protected CascadingAction<PersistContext> getCascadeAction() {
|
||||
return CascadingActions.SAVE_UPDATE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 java.util.IdentityHashMap;
|
||||
|
||||
/**
|
||||
* A {@link DeleteEvent} represents a {@linkplain org.hibernate.Session#delete(Object) delete operation}
|
||||
* applied to a single entity. A {@code DeleteContext} is propagated across all cascaded delete operations,
|
||||
* and keeps track of all the entities we've already visited.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public interface DeleteContext {
|
||||
|
||||
boolean add(Object entity);
|
||||
|
||||
static DeleteContext create() {
|
||||
// use extension to avoid creating
|
||||
// a useless wrapper object
|
||||
class Impl extends IdentityHashMap<Object,Object>
|
||||
implements DeleteContext {
|
||||
Impl() {
|
||||
super(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Object entity) {
|
||||
return put(entity,entity)==null;
|
||||
}
|
||||
}
|
||||
return new Impl();
|
||||
}
|
||||
}
|
|
@ -24,5 +24,5 @@ public interface DeleteEventListener {
|
|||
*/
|
||||
void onDelete(DeleteEvent event) throws HibernateException;
|
||||
|
||||
void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException;
|
||||
void onDelete(DeleteEvent event, DeleteContext transientEntities) throws HibernateException;
|
||||
}
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.event.spi;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.ActionQueue;
|
||||
import org.hibernate.engine.spi.EntityEntry;
|
||||
|
@ -43,20 +40,20 @@ public interface EventSource extends SessionImplementor {
|
|||
/**
|
||||
* Cascade persist an entity instance
|
||||
*/
|
||||
void persist(String entityName, Object object, Map createdAlready) throws HibernateException;
|
||||
void persist(String entityName, Object object, PersistContext createdAlready) throws HibernateException;
|
||||
|
||||
/**
|
||||
* Cascade persist an entity instance during the flush process
|
||||
*/
|
||||
void persistOnFlush(String entityName, Object object, Map copiedAlready);
|
||||
void persistOnFlush(String entityName, Object object, PersistContext copiedAlready);
|
||||
/**
|
||||
* Cascade refresh an entity instance
|
||||
*/
|
||||
void refresh(String entityName, Object object, Map refreshedAlready) throws HibernateException;
|
||||
void refresh(String entityName, Object object, RefreshContext refreshedAlready) throws HibernateException;
|
||||
/**
|
||||
* Cascade delete an entity instance
|
||||
*/
|
||||
void delete(String entityName, Object child, boolean isCascadeDeleteEnabled, Set transientEntities);
|
||||
void delete(String entityName, Object child, boolean isCascadeDeleteEnabled, DeleteContext transientEntities);
|
||||
/**
|
||||
* A specialized type of deletion for orphan removal that must occur prior to queued inserts and updates.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 java.util.IdentityHashMap;
|
||||
|
||||
/**
|
||||
* A {@link PersistEvent} represents a {@linkplain org.hibernate.Session#persist(Object) persist operation}
|
||||
* applied to a single entity. A {@code PersistContext} is propagated across all cascaded persist operations,
|
||||
* and keeps track of all the entities we've already visited.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public interface PersistContext {
|
||||
|
||||
boolean add(Object entity);
|
||||
|
||||
static PersistContext create() {
|
||||
// use extension to avoid creating
|
||||
// a useless wrapper object
|
||||
class Impl extends IdentityHashMap<Object,Object>
|
||||
implements PersistContext {
|
||||
Impl() {
|
||||
super(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Object entity) {
|
||||
return put(entity,entity)==null;
|
||||
}
|
||||
}
|
||||
return new Impl();
|
||||
}
|
||||
}
|
|
@ -29,6 +29,6 @@ public interface PersistEventListener {
|
|||
*
|
||||
* @param event The create event to be handled.
|
||||
*/
|
||||
void onPersist(PersistEvent event, Map createdAlready) throws HibernateException;
|
||||
void onPersist(PersistEvent event, PersistContext createdAlready) throws HibernateException;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 java.util.IdentityHashMap;
|
||||
|
||||
/**
|
||||
* A {@link RefreshEvent} represents a {@linkplain org.hibernate.Session#refresh(Object) refresh operation}
|
||||
* applied to a single entity. A {@code RefreshContext} is propagated across all cascaded refresh operations,
|
||||
* and keeps track of all the entities we've already visited.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public interface RefreshContext {
|
||||
|
||||
boolean add(Object entity);
|
||||
|
||||
static RefreshContext create() {
|
||||
// use extension to avoid creating
|
||||
// a useless wrapper object
|
||||
class Impl extends IdentityHashMap<Object,Object>
|
||||
implements RefreshContext {
|
||||
Impl() {
|
||||
super(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Object entity) {
|
||||
return put(entity,entity)==null;
|
||||
}
|
||||
}
|
||||
return new Impl();
|
||||
}
|
||||
}
|
|
@ -24,6 +24,6 @@ public interface RefreshEventListener {
|
|||
*/
|
||||
void onRefresh(RefreshEvent event) throws HibernateException;
|
||||
|
||||
void onRefresh(RefreshEvent event, Map refreshedAlready) throws HibernateException;
|
||||
void onRefresh(RefreshEvent event, RefreshContext refreshedAlready) throws HibernateException;
|
||||
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|||
import org.hibernate.engine.spi.Status;
|
||||
import org.hibernate.engine.transaction.spi.TransactionImplementor;
|
||||
import org.hibernate.engine.transaction.spi.TransactionObserver;
|
||||
import org.hibernate.event.spi.DeleteContext;
|
||||
import org.hibernate.event.spi.MergeContext;
|
||||
import org.hibernate.event.spi.AutoFlushEvent;
|
||||
import org.hibernate.event.spi.AutoFlushEventListener;
|
||||
|
@ -92,8 +93,10 @@ import org.hibernate.event.spi.LockEvent;
|
|||
import org.hibernate.event.spi.LockEventListener;
|
||||
import org.hibernate.event.spi.MergeEvent;
|
||||
import org.hibernate.event.spi.MergeEventListener;
|
||||
import org.hibernate.event.spi.PersistContext;
|
||||
import org.hibernate.event.spi.PersistEvent;
|
||||
import org.hibernate.event.spi.PersistEventListener;
|
||||
import org.hibernate.event.spi.RefreshContext;
|
||||
import org.hibernate.event.spi.RefreshEvent;
|
||||
import org.hibernate.event.spi.RefreshEventListener;
|
||||
import org.hibernate.event.spi.ReplicateEvent;
|
||||
|
@ -180,7 +183,8 @@ public class SessionImpl
|
|||
implements SessionImplementor, LoadAccessContext, EventSource {
|
||||
private static final EntityManagerMessageLogger log = HEMLogging.messageLogger( SessionImpl.class );
|
||||
|
||||
// Defaults to null which means the properties are the default - as defined in FastSessionServices#defaultSessionProperties
|
||||
// Defaults to null which means the properties are the default
|
||||
// as defined in FastSessionServices#defaultSessionProperties
|
||||
private Map<String, Object> properties;
|
||||
|
||||
private transient ActionQueue actionQueue;
|
||||
|
@ -191,7 +195,7 @@ public class SessionImpl
|
|||
private LockOptions lockOptions;
|
||||
|
||||
private boolean autoClear;
|
||||
private boolean autoClose;
|
||||
private final boolean autoClose;
|
||||
|
||||
private transient LoadEvent loadEvent; //cached LoadEvent instance
|
||||
|
||||
|
@ -210,7 +214,8 @@ public class SessionImpl
|
|||
|
||||
if ( options instanceof SharedSessionCreationOptions ) {
|
||||
final SharedSessionCreationOptions sharedOptions = (SharedSessionCreationOptions) options;
|
||||
final ActionQueue.TransactionCompletionProcesses transactionCompletionProcesses = sharedOptions.getTransactionCompletionProcesses();
|
||||
final ActionQueue.TransactionCompletionProcesses transactionCompletionProcesses
|
||||
= sharedOptions.getTransactionCompletionProcesses();
|
||||
if ( sharedOptions.isTransactionCoordinatorShared() && transactionCompletionProcesses != null ) {
|
||||
actionQueue.setTransactionCompletionProcesses(
|
||||
transactionCompletionProcesses,
|
||||
|
@ -237,13 +242,12 @@ public class SessionImpl
|
|||
|
||||
// do not override explicitly set flush mode ( SessionBuilder#flushMode() )
|
||||
if ( getHibernateFlushMode() == null ) {
|
||||
final FlushMode initialMode;
|
||||
if ( this.properties == null ) {
|
||||
initialMode = fastSessionServices.initialSessionFlushMode;
|
||||
}
|
||||
else {
|
||||
initialMode = ConfigurationHelper.getFlushMode( getSessionProperty( AvailableSettings.FLUSH_MODE ), FlushMode.AUTO );
|
||||
}
|
||||
final FlushMode initialMode = this.properties == null
|
||||
? fastSessionServices.initialSessionFlushMode
|
||||
: ConfigurationHelper.getFlushMode(
|
||||
getSessionProperty(AvailableSettings.FLUSH_MODE),
|
||||
FlushMode.AUTO
|
||||
);
|
||||
setHibernateFlushMode( initialMode );
|
||||
}
|
||||
|
||||
|
@ -264,7 +268,7 @@ public class SessionImpl
|
|||
}
|
||||
|
||||
if ( log.isTraceEnabled() ) {
|
||||
log.tracef( "Opened Session [%s] at timestamp: %s", getSessionIdentifier(), getTimestamp() );
|
||||
log.tracef( "Opened Session [%s] at timestamp: %s", getSessionIdentifier(), getTransactionStartTimestamp() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +362,8 @@ public class SessionImpl
|
|||
persistenceContext.clear();
|
||||
actionQueue.clear();
|
||||
|
||||
fastSessionServices.eventListenerGroup_CLEAR.fireLazyEventOnEachListener( this::createClearEvent, ClearEventListener::onClear );
|
||||
fastSessionServices.eventListenerGroup_CLEAR
|
||||
.fireLazyEventOnEachListener( this::createClearEvent, ClearEventListener::onClear );
|
||||
}
|
||||
|
||||
private ClearEvent createClearEvent() {
|
||||
|
@ -390,7 +395,7 @@ public class SessionImpl
|
|||
// Original hibernate-entitymanager EM#close behavior
|
||||
checkSessionFactoryOpen();
|
||||
checkOpenOrWaitingForAutoClose();
|
||||
if ( fastSessionServices.discardOnClose || !isTransactionInProgress( false ) ) {
|
||||
if ( fastSessionServices.discardOnClose || !isTransactionInProgressAndNotMarkedForRollback() ) {
|
||||
super.close();
|
||||
}
|
||||
else {
|
||||
|
@ -408,13 +413,15 @@ public class SessionImpl
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isTransactionInProgress(boolean isMarkedRollbackConsideredActive) {
|
||||
private boolean isTransactionInProgressAndNotMarkedForRollback() {
|
||||
if ( waitingForAutoClose ) {
|
||||
return getSessionFactory().isOpen() &&
|
||||
getTransactionCoordinator().isTransactionActive( isMarkedRollbackConsideredActive );
|
||||
return getSessionFactory().isOpen()
|
||||
&& getTransactionCoordinator().isTransactionActive( false );
|
||||
}
|
||||
else {
|
||||
return !isClosed()
|
||||
&& getTransactionCoordinator().isTransactionActive( false );
|
||||
}
|
||||
return !isClosed() &&
|
||||
getTransactionCoordinator().isTransactionActive( isMarkedRollbackConsideredActive );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -578,8 +585,9 @@ public class SessionImpl
|
|||
|
||||
@Override
|
||||
public void delayedAfterCompletion() {
|
||||
if ( getTransactionCoordinator() instanceof JtaTransactionCoordinatorImpl ) {
|
||||
( (JtaTransactionCoordinatorImpl) getTransactionCoordinator() ).getSynchronizationCallbackCoordinator()
|
||||
TransactionCoordinator coordinator = getTransactionCoordinator();
|
||||
if ( coordinator instanceof JtaTransactionCoordinatorImpl ) {
|
||||
( (JtaTransactionCoordinatorImpl) coordinator).getSynchronizationCallbackCoordinator()
|
||||
.processAnyDelayedAfterCompletion();
|
||||
}
|
||||
}
|
||||
|
@ -610,7 +618,8 @@ public class SessionImpl
|
|||
checkOpen();
|
||||
checkTransactionSynchStatus();
|
||||
checkNoUnresolvedActionsBeforeOperation();
|
||||
fastSessionServices.eventListenerGroup_SAVE_UPDATE.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
|
||||
fastSessionServices.eventListenerGroup_SAVE_UPDATE
|
||||
.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
|
||||
checkNoUnresolvedActionsAfterOperation();
|
||||
}
|
||||
|
||||
|
@ -630,7 +639,8 @@ public class SessionImpl
|
|||
checkOpen();
|
||||
checkTransactionSynchStatus();
|
||||
checkNoUnresolvedActionsBeforeOperation();
|
||||
fastSessionServices.eventListenerGroup_SAVE.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
|
||||
fastSessionServices.eventListenerGroup_SAVE
|
||||
.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
|
||||
checkNoUnresolvedActionsAfterOperation();
|
||||
return event.getResultId();
|
||||
}
|
||||
|
@ -652,7 +662,8 @@ public class SessionImpl
|
|||
checkOpen();
|
||||
checkTransactionSynchStatus();
|
||||
checkNoUnresolvedActionsBeforeOperation();
|
||||
fastSessionServices.eventListenerGroup_UPDATE.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
|
||||
fastSessionServices.eventListenerGroup_UPDATE
|
||||
.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
|
||||
checkNoUnresolvedActionsAfterOperation();
|
||||
}
|
||||
|
||||
|
@ -685,7 +696,8 @@ public class SessionImpl
|
|||
private void fireLock(LockEvent event) {
|
||||
checkOpen();
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_LOCK.fireEventOnEachListener( event, LockEventListener::onLock );
|
||||
fastSessionServices.eventListenerGroup_LOCK
|
||||
.fireEventOnEachListener( event, LockEventListener::onLock );
|
||||
delayedAfterCompletion();
|
||||
}
|
||||
|
||||
|
@ -704,7 +716,7 @@ public class SessionImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void persist(String entityName, Object object, Map copiedAlready) throws HibernateException {
|
||||
public void persist(String entityName, Object object, PersistContext copiedAlready) throws HibernateException {
|
||||
checkOpenOrWaitingForAutoClose();
|
||||
firePersist( copiedAlready, new PersistEvent( entityName, object, this ) );
|
||||
}
|
||||
|
@ -715,7 +727,8 @@ public class SessionImpl
|
|||
checkTransactionSynchStatus();
|
||||
checkNoUnresolvedActionsBeforeOperation();
|
||||
|
||||
fastSessionServices.eventListenerGroup_PERSIST.fireEventOnEachListener( event, PersistEventListener::onPersist );
|
||||
fastSessionServices.eventListenerGroup_PERSIST
|
||||
.fireEventOnEachListener( event, PersistEventListener::onPersist );
|
||||
}
|
||||
catch (MappingException e) {
|
||||
originalException = getExceptionConverter().convert( new IllegalArgumentException( e.getMessage() ) );
|
||||
|
@ -751,7 +764,7 @@ public class SessionImpl
|
|||
}
|
||||
}
|
||||
|
||||
private void firePersist(final Map copiedAlready, final PersistEvent event) {
|
||||
private void firePersist(final PersistContext copiedAlready, final PersistEvent event) {
|
||||
pulseTransactionCoordinator();
|
||||
|
||||
try {
|
||||
|
@ -774,11 +787,12 @@ public class SessionImpl
|
|||
// persistOnFlush() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public void persistOnFlush(String entityName, Object object, Map copiedAlready) {
|
||||
public void persistOnFlush(String entityName, Object object, PersistContext copiedAlready) {
|
||||
checkOpenOrWaitingForAutoClose();
|
||||
pulseTransactionCoordinator();
|
||||
PersistEvent event = new PersistEvent( entityName, object, this );
|
||||
fastSessionServices.eventListenerGroup_PERSIST_ONFLUSH.fireEventOnEachListener( event, copiedAlready, PersistEventListener::onPersist );
|
||||
fastSessionServices.eventListenerGroup_PERSIST_ONFLUSH
|
||||
.fireEventOnEachListener( event, copiedAlready, PersistEventListener::onPersist );
|
||||
delayedAfterCompletion();
|
||||
}
|
||||
|
||||
|
@ -806,7 +820,8 @@ public class SessionImpl
|
|||
try {
|
||||
checkTransactionSynchStatus();
|
||||
checkNoUnresolvedActionsBeforeOperation();
|
||||
fastSessionServices.eventListenerGroup_MERGE.fireEventOnEachListener( event, MergeEventListener::onMerge );
|
||||
fastSessionServices.eventListenerGroup_MERGE
|
||||
.fireEventOnEachListener( event, MergeEventListener::onMerge );
|
||||
checkNoUnresolvedActionsAfterOperation();
|
||||
}
|
||||
catch ( ObjectDeletedException sse ) {
|
||||
|
@ -826,7 +841,8 @@ public class SessionImpl
|
|||
private void fireMerge(final MergeContext mergeContext, final MergeEvent event) {
|
||||
try {
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_MERGE.fireEventOnEachListener( event, mergeContext, MergeEventListener::onMerge );
|
||||
fastSessionServices.eventListenerGroup_MERGE
|
||||
.fireEventOnEachListener( event, mergeContext, MergeEventListener::onMerge );
|
||||
}
|
||||
catch ( ObjectDeletedException sse ) {
|
||||
throw getExceptionConverter().convert( new IllegalArgumentException( sse ) );
|
||||
|
@ -859,7 +875,7 @@ public class SessionImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void delete(String entityName, Object object, boolean isCascadeDeleteEnabled, Set transientEntities)
|
||||
public void delete(String entityName, Object object, boolean isCascadeDeleteEnabled, DeleteContext transientEntities)
|
||||
throws HibernateException {
|
||||
checkOpenOrWaitingForAutoClose();
|
||||
final boolean removingOrphanBeforeUpates = persistenceContext.isRemovingOrphanBeforeUpates();
|
||||
|
@ -917,7 +933,8 @@ public class SessionImpl
|
|||
private void fireDelete(final DeleteEvent event) {
|
||||
try{
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_DELETE.fireEventOnEachListener( event, DeleteEventListener::onDelete );
|
||||
fastSessionServices.eventListenerGroup_DELETE
|
||||
.fireEventOnEachListener( event, DeleteEventListener::onDelete );
|
||||
}
|
||||
catch ( ObjectDeletedException sse ) {
|
||||
throw getExceptionConverter().convert( new IllegalArgumentException( sse ) );
|
||||
|
@ -934,10 +951,11 @@ public class SessionImpl
|
|||
}
|
||||
}
|
||||
|
||||
private void fireDelete(final DeleteEvent event, final Set transientEntities) {
|
||||
private void fireDelete(final DeleteEvent event, final DeleteContext transientEntities) {
|
||||
try{
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_DELETE.fireEventOnEachListener( event, transientEntities, DeleteEventListener::onDelete );
|
||||
fastSessionServices.eventListenerGroup_DELETE
|
||||
.fireEventOnEachListener( event, transientEntities, DeleteEventListener::onDelete );
|
||||
}
|
||||
catch ( ObjectDeletedException sse ) {
|
||||
throw getExceptionConverter().convert( new IllegalArgumentException( sse ) );
|
||||
|
@ -1215,13 +1233,15 @@ public class SessionImpl
|
|||
// it seems they prevent these hot methods from being inlined.
|
||||
private void fireLoadNoChecks(final LoadEvent event, final LoadType loadType) {
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_LOAD.fireEventOnEachListener( event, loadType, LoadEventListener::onLoad );
|
||||
fastSessionServices.eventListenerGroup_LOAD
|
||||
.fireEventOnEachListener( event, loadType, LoadEventListener::onLoad );
|
||||
}
|
||||
|
||||
private void fireResolveNaturalId(final ResolveNaturalIdEvent event) {
|
||||
checkOpenOrWaitingForAutoClose();
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_RESOLVE_NATURAL_ID.fireEventOnEachListener( event, ResolveNaturalIdEventListener::onResolveNaturalId );
|
||||
fastSessionServices.eventListenerGroup_RESOLVE_NATURAL_ID
|
||||
.fireEventOnEachListener( event, ResolveNaturalIdEventListener::onResolveNaturalId );
|
||||
delayedAfterCompletion();
|
||||
}
|
||||
|
||||
|
@ -1259,7 +1279,7 @@ public class SessionImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void refresh(String entityName, Object object, Map refreshedAlready) throws HibernateException {
|
||||
public void refresh(String entityName, Object object, RefreshContext refreshedAlready) throws HibernateException {
|
||||
checkOpenOrWaitingForAutoClose();
|
||||
fireRefresh( refreshedAlready, new RefreshEvent( entityName, object, this ) );
|
||||
}
|
||||
|
@ -1279,7 +1299,8 @@ public class SessionImpl
|
|||
}
|
||||
}
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_REFRESH.fireEventOnEachListener( event, RefreshEventListener::onRefresh );
|
||||
fastSessionServices.eventListenerGroup_REFRESH
|
||||
.fireEventOnEachListener( event, RefreshEventListener::onRefresh );
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
if ( !getSessionFactory().getSessionFactoryOptions().isJpaBootstrap() ) {
|
||||
|
@ -1295,10 +1316,11 @@ public class SessionImpl
|
|||
}
|
||||
}
|
||||
|
||||
private void fireRefresh(final Map refreshedAlready, final RefreshEvent event) {
|
||||
private void fireRefresh(final RefreshContext refreshedAlready, final RefreshEvent event) {
|
||||
try {
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_REFRESH.fireEventOnEachListener( event, refreshedAlready, RefreshEventListener::onRefresh );
|
||||
fastSessionServices.eventListenerGroup_REFRESH
|
||||
.fireEventOnEachListener( event, refreshedAlready, RefreshEventListener::onRefresh );
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
throw getExceptionConverter().convert( e );
|
||||
|
@ -1325,7 +1347,8 @@ public class SessionImpl
|
|||
private void fireReplicate(final ReplicateEvent event) {
|
||||
checkOpen();
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_REPLICATE.fireEventOnEachListener( event, ReplicateEventListener::onReplicate );
|
||||
fastSessionServices.eventListenerGroup_REPLICATE
|
||||
.fireEventOnEachListener( event, ReplicateEventListener::onReplicate );
|
||||
delayedAfterCompletion();
|
||||
}
|
||||
|
||||
|
@ -1341,7 +1364,8 @@ public class SessionImpl
|
|||
checkOpen();
|
||||
pulseTransactionCoordinator();
|
||||
final EvictEvent event = new EvictEvent( object, this );
|
||||
fastSessionServices.eventListenerGroup_EVICT.fireEventOnEachListener( event, EvictEventListener::onEvict );
|
||||
fastSessionServices.eventListenerGroup_EVICT
|
||||
.fireEventOnEachListener( event, EvictEventListener::onEvict );
|
||||
delayedAfterCompletion();
|
||||
}
|
||||
|
||||
|
@ -1353,7 +1377,8 @@ public class SessionImpl
|
|||
return false;
|
||||
}
|
||||
AutoFlushEvent event = new AutoFlushEvent( querySpaces, this );
|
||||
fastSessionServices.eventListenerGroup_AUTO_FLUSH.fireEventOnEachListener( event, AutoFlushEventListener::onAutoFlush );
|
||||
fastSessionServices.eventListenerGroup_AUTO_FLUSH
|
||||
.fireEventOnEachListener( event, AutoFlushEventListener::onAutoFlush );
|
||||
return event.isFlushRequired();
|
||||
}
|
||||
|
||||
|
@ -1367,7 +1392,8 @@ public class SessionImpl
|
|||
return true;
|
||||
}
|
||||
DirtyCheckEvent event = new DirtyCheckEvent( this );
|
||||
fastSessionServices.eventListenerGroup_DIRTY_CHECK.fireEventOnEachListener( event, DirtyCheckEventListener::onDirtyCheck );
|
||||
fastSessionServices.eventListenerGroup_DIRTY_CHECK
|
||||
.fireEventOnEachListener( event, DirtyCheckEventListener::onDirtyCheck );
|
||||
delayedAfterCompletion();
|
||||
return event.isDirty();
|
||||
}
|
||||
|
@ -1388,7 +1414,8 @@ public class SessionImpl
|
|||
}
|
||||
|
||||
FlushEvent event = new FlushEvent( this );
|
||||
fastSessionServices.eventListenerGroup_FLUSH.fireEventOnEachListener( event, FlushEventListener::onFlush );
|
||||
fastSessionServices.eventListenerGroup_FLUSH
|
||||
.fireEventOnEachListener( event, FlushEventListener::onFlush );
|
||||
delayedAfterCompletion();
|
||||
}
|
||||
catch ( RuntimeException e ) {
|
||||
|
@ -1676,7 +1703,8 @@ public class SessionImpl
|
|||
checkOpenOrWaitingForAutoClose();
|
||||
pulseTransactionCoordinator();
|
||||
InitializeCollectionEvent event = new InitializeCollectionEvent( collection, this );
|
||||
fastSessionServices.eventListenerGroup_INIT_COLLECTION.fireEventOnEachListener( event, InitializeCollectionEventListener::onInitializeCollection );
|
||||
fastSessionServices.eventListenerGroup_INIT_COLLECTION
|
||||
.fireEventOnEachListener( event, InitializeCollectionEventListener::onInitializeCollection );
|
||||
delayedAfterCompletion();
|
||||
}
|
||||
|
||||
|
@ -2576,7 +2604,8 @@ public class SessionImpl
|
|||
|
||||
private Map<String, Object> computeCurrentSessionProperties() {
|
||||
final HashMap<String, Object> map = new HashMap<>( fastSessionServices.defaultSessionProperties );
|
||||
//The FLUSH_MODE is always set at Session creation time, so it needs special treatment to not eagerly initialize this Map:
|
||||
//The FLUSH_MODE is always set at Session creation time,
|
||||
//so it needs special treatment to not eagerly initialize this Map:
|
||||
map.put( AvailableSettings.FLUSH_MODE, getHibernateFlushMode().name() );
|
||||
return map;
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ public interface ClassMetadata {
|
|||
*/
|
||||
@Deprecated(since = "5.3")
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
default Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session)
|
||||
default Object[] getPropertyValuesToInsert(Object entity, Map<Object,Object> mergeMap, SessionImplementor session)
|
||||
throws HibernateException {
|
||||
return getPropertyValuesToInsert( entity, mergeMap, (SharedSessionContractImplementor) session );
|
||||
}
|
||||
|
@ -134,7 +134,8 @@ public interface ClassMetadata {
|
|||
* Return the values of the mapped properties of the object
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SharedSessionContractImplementor session) throws HibernateException;
|
||||
Object[] getPropertyValuesToInsert(Object entity, Map<Object,Object> mergeMap, SharedSessionContractImplementor session)
|
||||
throws HibernateException;
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -144,7 +145,7 @@ public interface ClassMetadata {
|
|||
/**
|
||||
* The persistent class, or null
|
||||
*/
|
||||
Class getMappedClass();
|
||||
Class<?> getMappedClass();
|
||||
|
||||
/**
|
||||
* Create a class instance initialized with the given identifier
|
||||
|
|
|
@ -5162,7 +5162,10 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SharedSessionContractImplementor session)
|
||||
public Object[] getPropertyValuesToInsert(
|
||||
Object entity,
|
||||
Map<Object,Object> mergeMap,
|
||||
SharedSessionContractImplementor session)
|
||||
throws HibernateException {
|
||||
if ( shouldGetAllProperties( entity ) && accessOptimizer != null ) {
|
||||
return accessOptimizer.getPropertyValues( entity );
|
||||
|
|
|
@ -760,7 +760,7 @@ public interface EntityPersister
|
|||
/**
|
||||
* Return the values of the insertable properties of the object (including backrefs)
|
||||
*/
|
||||
Object[] getPropertyValuesToInsert(Object object, Map mergeMap, SharedSessionContractImplementor session);
|
||||
Object[] getPropertyValuesToInsert(Object object, Map<Object,Object> mergeMap, SharedSessionContractImplementor session);
|
||||
|
||||
/**
|
||||
* Perform a select to retrieve the values of any generated properties
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.events;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.SessionFactoryObserver;
|
||||
|
@ -16,6 +14,7 @@ import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
|||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||
import org.hibernate.event.spi.DeleteContext;
|
||||
import org.hibernate.event.spi.DeleteEvent;
|
||||
import org.hibernate.event.spi.DeleteEventListener;
|
||||
import org.hibernate.event.spi.EventType;
|
||||
|
@ -135,7 +134,7 @@ public class CallbackTest extends BaseCoreFunctionalTestCase {
|
|||
public void onDelete(DeleteEvent event) throws HibernateException {
|
||||
}
|
||||
|
||||
public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {
|
||||
public void onDelete(DeleteEvent event, DeleteContext transientEntities) throws HibernateException {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
package org.hibernate.orm.test.jpa.model;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.IdentityHashMap;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.boot.Metadata;
|
||||
|
@ -27,6 +26,7 @@ import org.hibernate.event.spi.AutoFlushEventListener;
|
|||
import org.hibernate.event.spi.EventType;
|
||||
import org.hibernate.event.spi.FlushEntityEventListener;
|
||||
import org.hibernate.event.spi.FlushEventListener;
|
||||
import org.hibernate.event.spi.PersistContext;
|
||||
import org.hibernate.event.spi.PersistEventListener;
|
||||
import org.hibernate.integrator.spi.Integrator;
|
||||
import org.hibernate.proxy.EntityNotFoundDelegate;
|
||||
|
@ -132,7 +132,7 @@ public abstract class AbstractJPATest extends BaseSessionFactoryFunctionalTest {
|
|||
|
||||
public static class JPAPersistOnFlushEventListener extends JPAPersistEventListener {
|
||||
@Override
|
||||
protected CascadingAction getCascadeAction() {
|
||||
protected CascadingAction<PersistContext> getCascadeAction() {
|
||||
return CascadingActions.PERSIST_ON_FLUSH;
|
||||
}
|
||||
}
|
||||
|
@ -142,13 +142,13 @@ public abstract class AbstractJPATest extends BaseSessionFactoryFunctionalTest {
|
|||
public static final AutoFlushEventListener INSTANCE = new JPAAutoFlushEventListener();
|
||||
|
||||
@Override
|
||||
protected CascadingAction getCascadingAction() {
|
||||
protected CascadingAction<PersistContext> getCascadingAction() {
|
||||
return CascadingActions.PERSIST_ON_FLUSH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getAnything() {
|
||||
return new IdentityHashMap( 10 );
|
||||
protected PersistContext getContext() {
|
||||
return PersistContext.create();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,13 +157,13 @@ public abstract class AbstractJPATest extends BaseSessionFactoryFunctionalTest {
|
|||
public static final FlushEventListener INSTANCE = new JPAFlushEventListener();
|
||||
|
||||
@Override
|
||||
protected CascadingAction getCascadingAction() {
|
||||
protected CascadingAction<PersistContext> getCascadingAction() {
|
||||
return CascadingActions.PERSIST_ON_FLUSH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getAnything() {
|
||||
return new IdentityHashMap( 10 );
|
||||
protected PersistContext getContext() {
|
||||
return PersistContext.create();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue