HHH-9106 : Merging multiple representations of the same entity (using StrategySelector)
(cherry picked from commit 6203b5da30
)
This commit is contained in:
parent
b0a2ae9d66
commit
1472681dc2
|
@ -93,6 +93,10 @@ import org.hibernate.engine.transaction.jta.platform.internal.WebSphereJtaPlatfo
|
||||||
import org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform;
|
import org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform;
|
||||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||||
|
import org.hibernate.event.internal.EntityCopyAllowedLoggedObserver;
|
||||||
|
import org.hibernate.event.internal.EntityCopyAllowedObserver;
|
||||||
|
import org.hibernate.event.internal.EntityCopyNotAllowedObserver;
|
||||||
|
import org.hibernate.event.spi.EntityCopyObserver;
|
||||||
import org.hibernate.hql.spi.MultiTableBulkIdStrategy;
|
import org.hibernate.hql.spi.MultiTableBulkIdStrategy;
|
||||||
import org.hibernate.hql.spi.PersistentTableBulkIdStrategy;
|
import org.hibernate.hql.spi.PersistentTableBulkIdStrategy;
|
||||||
import org.hibernate.hql.spi.TemporaryTableBulkIdStrategy;
|
import org.hibernate.hql.spi.TemporaryTableBulkIdStrategy;
|
||||||
|
@ -163,6 +167,7 @@ public class StrategySelectorBuilder {
|
||||||
addJtaPlatforms( strategySelector );
|
addJtaPlatforms( strategySelector );
|
||||||
addTransactionFactories( strategySelector );
|
addTransactionFactories( strategySelector );
|
||||||
addMultiTableBulkIdStrategies( strategySelector );
|
addMultiTableBulkIdStrategies( strategySelector );
|
||||||
|
addEntityCopyObserverStrategies( strategySelector );
|
||||||
|
|
||||||
// apply auto-discovered registrations
|
// apply auto-discovered registrations
|
||||||
for ( StrategyRegistrationProvider provider : classLoaderService.loadJavaServices( StrategyRegistrationProvider.class ) ) {
|
for ( StrategyRegistrationProvider provider : classLoaderService.loadJavaServices( StrategyRegistrationProvider.class ) ) {
|
||||||
|
@ -373,4 +378,22 @@ public class StrategySelectorBuilder {
|
||||||
TemporaryTableBulkIdStrategy.class
|
TemporaryTableBulkIdStrategy.class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addEntityCopyObserverStrategies(StrategySelectorImpl strategySelector) {
|
||||||
|
strategySelector.registerStrategyImplementor(
|
||||||
|
EntityCopyObserver.class,
|
||||||
|
EntityCopyNotAllowedObserver.SHORT_NAME,
|
||||||
|
EntityCopyNotAllowedObserver.class
|
||||||
|
);
|
||||||
|
strategySelector.registerStrategyImplementor(
|
||||||
|
EntityCopyObserver.class,
|
||||||
|
EntityCopyAllowedObserver.SHORT_NAME,
|
||||||
|
EntityCopyAllowedObserver.class
|
||||||
|
);
|
||||||
|
strategySelector.registerStrategyImplementor(
|
||||||
|
EntityCopyObserver.class,
|
||||||
|
EntityCopyAllowedLoggedObserver.SHORT_NAME,
|
||||||
|
EntityCopyAllowedLoggedObserver.class
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,14 +31,18 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.ObjectDeletedException;
|
import org.hibernate.ObjectDeletedException;
|
||||||
import org.hibernate.StaleObjectStateException;
|
import org.hibernate.StaleObjectStateException;
|
||||||
import org.hibernate.WrongClassException;
|
import org.hibernate.WrongClassException;
|
||||||
|
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||||
import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor;
|
import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor;
|
||||||
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
import org.hibernate.engine.internal.Cascade;
|
import org.hibernate.engine.internal.Cascade;
|
||||||
import org.hibernate.engine.internal.CascadePoint;
|
import org.hibernate.engine.internal.CascadePoint;
|
||||||
import org.hibernate.engine.spi.CascadingAction;
|
import org.hibernate.engine.spi.CascadingAction;
|
||||||
import org.hibernate.engine.spi.CascadingActions;
|
import org.hibernate.engine.spi.CascadingActions;
|
||||||
import org.hibernate.engine.spi.EntityEntry;
|
import org.hibernate.engine.spi.EntityEntry;
|
||||||
import org.hibernate.engine.spi.EntityKey;
|
import org.hibernate.engine.spi.EntityKey;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
|
import org.hibernate.event.spi.EntityCopyObserver;
|
||||||
import org.hibernate.event.spi.EventSource;
|
import org.hibernate.event.spi.EventSource;
|
||||||
import org.hibernate.event.spi.MergeEvent;
|
import org.hibernate.event.spi.MergeEvent;
|
||||||
import org.hibernate.event.spi.MergeEventListener;
|
import org.hibernate.event.spi.MergeEventListener;
|
||||||
|
@ -47,6 +51,7 @@ import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.hibernate.proxy.LazyInitializer;
|
import org.hibernate.proxy.LazyInitializer;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.ForeignKeyDirection;
|
import org.hibernate.type.ForeignKeyDirection;
|
||||||
import org.hibernate.type.TypeHelper;
|
import org.hibernate.type.TypeHelper;
|
||||||
|
|
||||||
|
@ -59,15 +64,13 @@ import org.hibernate.type.TypeHelper;
|
||||||
public class DefaultMergeEventListener extends AbstractSaveEventListener implements MergeEventListener {
|
public class DefaultMergeEventListener extends AbstractSaveEventListener implements MergeEventListener {
|
||||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultMergeEventListener.class );
|
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultMergeEventListener.class );
|
||||||
|
|
||||||
|
private String entityCopyObserverStrategy;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map getMergeMap(Object anything) {
|
protected Map getMergeMap(Object anything) {
|
||||||
return ( (MergeContext) anything ).invertMap();
|
return ( (MergeContext) anything ).invertMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EntityCopyObserver createEntityCopyObserver() {
|
|
||||||
return new EntityCopyNotAllowedObserver();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the given merge event.
|
* Handle the given merge event.
|
||||||
*
|
*
|
||||||
|
@ -76,7 +79,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
||||||
* @throws HibernateException
|
* @throws HibernateException
|
||||||
*/
|
*/
|
||||||
public void onMerge(MergeEvent event) throws HibernateException {
|
public void onMerge(MergeEvent event) throws HibernateException {
|
||||||
final EntityCopyObserver entityCopyObserver = createEntityCopyObserver();
|
final EntityCopyObserver entityCopyObserver = createEntityCopyObserver( event.getSession().getFactory() );
|
||||||
final MergeContext mergeContext = new MergeContext( event.getSession(), entityCopyObserver );
|
final MergeContext mergeContext = new MergeContext( event.getSession(), entityCopyObserver );
|
||||||
try {
|
try {
|
||||||
onMerge( event, mergeContext );
|
onMerge( event, mergeContext );
|
||||||
|
@ -88,6 +91,27 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EntityCopyObserver createEntityCopyObserver(SessionFactoryImplementor sessionFactory) {
|
||||||
|
final ServiceRegistry serviceRegistry = sessionFactory.getServiceRegistry();
|
||||||
|
if ( entityCopyObserverStrategy == null ) {
|
||||||
|
final ConfigurationService configurationService
|
||||||
|
= serviceRegistry.getService( ConfigurationService.class );
|
||||||
|
entityCopyObserverStrategy = configurationService.getSetting(
|
||||||
|
"hibernate.event.merge.entity_copy_observer",
|
||||||
|
new ConfigurationService.Converter<String>() {
|
||||||
|
@Override
|
||||||
|
public String convert(Object value) {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
EntityCopyNotAllowedObserver.SHORT_NAME
|
||||||
|
);
|
||||||
|
LOG.debugf( "EntityCopyObserver strategy: %s", entityCopyObserverStrategy );
|
||||||
|
}
|
||||||
|
final StrategySelector strategySelector = serviceRegistry.getService( StrategySelector.class );
|
||||||
|
return strategySelector.resolveStrategy( EntityCopyObserver.class, entityCopyObserverStrategy );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the given merge event.
|
* Handle the given merge event.
|
||||||
*
|
*
|
||||||
|
|
|
@ -35,7 +35,7 @@ import org.hibernate.internal.util.collections.IdentitySet;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link EntityCopyObserver} implementation that allows multiple representations of
|
* An {@link org.hibernate.event.spi.EntityCopyObserver} implementation that allows multiple representations of
|
||||||
* the same persistent entity to be merged and provides logging of the entity copies that
|
* the same persistent entity to be merged and provides logging of the entity copies that
|
||||||
* that are detected.
|
* that are detected.
|
||||||
*
|
*
|
||||||
|
@ -44,6 +44,8 @@ import org.hibernate.pretty.MessageHelper;
|
||||||
public class EntityCopyAllowedLoggedObserver extends EntityCopyAllowedObserver {
|
public class EntityCopyAllowedLoggedObserver extends EntityCopyAllowedObserver {
|
||||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( EntityCopyAllowedLoggedObserver.class );
|
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( EntityCopyAllowedLoggedObserver.class );
|
||||||
|
|
||||||
|
public static final String SHORT_NAME = "log";
|
||||||
|
|
||||||
// Tracks the number of entity copies per entity name.
|
// Tracks the number of entity copies per entity name.
|
||||||
private Map<String, Integer> countsByEntityName;
|
private Map<String, Integer> countsByEntityName;
|
||||||
|
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.hibernate.event.internal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link org.hibernate.event.spi.MergeEventListener} that allows merging
|
|
||||||
* multiple representations of the same persistent entity.
|
|
||||||
*
|
|
||||||
* @author Gail Badner
|
|
||||||
*/
|
|
||||||
public class EntityCopyAllowedMergeEventListener extends DefaultMergeEventListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected EntityCopyObserver createEntityCopyObserver() {
|
|
||||||
return EntityCopyAllowedLoggedObserver.isDebugLoggingEnabled() ?
|
|
||||||
new EntityCopyAllowedLoggedObserver() :
|
|
||||||
new EntityCopyAllowedObserver();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,23 +23,19 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.event.internal;
|
package org.hibernate.event.internal;
|
||||||
|
|
||||||
import java.util.IdentityHashMap;
|
import org.hibernate.event.spi.EntityCopyObserver;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.hibernate.event.spi.EventSource;
|
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.pretty.MessageHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link EntityCopyObserver} implementation that allows multiple representations of
|
* An {@link org.hibernate.event.spi.EntityCopyObserver} implementation that allows multiple representations of
|
||||||
* the same persistent entity to be merged.
|
* the same persistent entity to be merged.
|
||||||
*
|
*
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
public class EntityCopyAllowedObserver implements EntityCopyObserver {
|
public class EntityCopyAllowedObserver implements EntityCopyObserver {
|
||||||
|
|
||||||
|
public static final String SHORT_NAME = "allow";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void entityCopyDetected(
|
public void entityCopyDetected(
|
||||||
Object managedEntity,
|
Object managedEntity,
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
package org.hibernate.event.internal;
|
package org.hibernate.event.internal;
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
|
import org.hibernate.event.spi.EntityCopyObserver;
|
||||||
import org.hibernate.event.spi.EventSource;
|
import org.hibernate.event.spi.EventSource;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
|
|
||||||
|
@ -32,6 +33,8 @@ import org.hibernate.pretty.MessageHelper;
|
||||||
*/
|
*/
|
||||||
public class EntityCopyNotAllowedObserver implements EntityCopyObserver {
|
public class EntityCopyNotAllowedObserver implements EntityCopyObserver {
|
||||||
|
|
||||||
|
public static final String SHORT_NAME = "disallow";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void entityCopyDetected(
|
public void entityCopyDetected(
|
||||||
Object managedEntity,
|
Object managedEntity,
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.event.spi.EntityCopyObserver;
|
||||||
import org.hibernate.event.spi.EventSource;
|
import org.hibernate.event.spi.EventSource;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ import org.hibernate.pretty.MessageHelper;
|
||||||
* MergeContext already contains an entry with a different entity as the key, but
|
* MergeContext already contains an entry with a different entity as the key, but
|
||||||
* with the same (managedEntity) value, this means that multiple entity representations
|
* with the same (managedEntity) value, this means that multiple entity representations
|
||||||
* for the same persistent entity are being merged. If this happens,
|
* for the same persistent entity are being merged. If this happens,
|
||||||
* {@link org.hibernate.event.internal.EntityCopyObserver#entityCopyDetected(
|
* {@link org.hibernate.event.spi.EntityCopyObserver#entityCopyDetected(
|
||||||
* Object managedEntity, Object mergeEntity1, Object mergeEntity2, org.hibernate.event.spi.EventSource)}
|
* Object managedEntity, Object mergeEntity1, Object mergeEntity2, org.hibernate.event.spi.EventSource)}
|
||||||
* will be called. It is up to that method to determine the property course of
|
* will be called. It is up to that method to determine the property course of
|
||||||
* action for this situation.
|
* action for this situation.
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.event.internal;
|
package org.hibernate.event.spi;
|
||||||
|
|
||||||
import org.hibernate.event.spi.EventSource;
|
import org.hibernate.event.spi.EventSource;
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.event.spi.EntityCopyObserver;
|
||||||
import org.hibernate.event.spi.EventSource;
|
import org.hibernate.event.spi.EventSource;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,6 @@ import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.event.internal.EntityCopyAllowedMergeEventListener;
|
|
||||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
|
||||||
import org.hibernate.event.spi.EventType;
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,8 @@ import org.junit.Test;
|
||||||
import org.hibernate.Hibernate;
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.event.internal.EntityCopyAllowedMergeEventListener;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
|
||||||
import org.hibernate.event.spi.EventType;
|
|
||||||
import org.hibernate.testing.FailureExpected;
|
import org.hibernate.testing.FailureExpected;
|
||||||
import org.hibernate.testing.TestForIssue;
|
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
@ -57,9 +54,12 @@ public class MergeMultipleEntityRepresentationsOrphanDeleteTest extends BaseCore
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void afterSessionFactoryBuilt() {
|
public void configure(Configuration cfg) {
|
||||||
EventListenerRegistry registry = sessionFactory().getServiceRegistry().getService( EventListenerRegistry.class );
|
super.configure( cfg );
|
||||||
registry.setListeners( EventType.MERGE, new EntityCopyAllowedMergeEventListener() );
|
cfg.setProperty(
|
||||||
|
"hibernate.event.merge.entity_copy_observer",
|
||||||
|
"allow"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -31,9 +31,7 @@ import org.hibernate.Hibernate;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.StaleObjectStateException;
|
import org.hibernate.StaleObjectStateException;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.event.internal.EntityCopyAllowedMergeEventListener;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
|
||||||
import org.hibernate.event.spi.EventType;
|
|
||||||
import org.hibernate.testing.FailureExpected;
|
import org.hibernate.testing.FailureExpected;
|
||||||
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
|
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
@ -58,9 +56,12 @@ public class MergeMultipleEntityRepresentationsTest extends BaseCoreFunctionalTe
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void afterSessionFactoryBuilt() {
|
public void configure(Configuration cfg) {
|
||||||
EventListenerRegistry registry = sessionFactory().getServiceRegistry().getService( EventListenerRegistry.class );
|
super.configure( cfg );
|
||||||
registry.setListeners( EventType.MERGE, new EntityCopyAllowedMergeEventListener() );
|
cfg.setProperty(
|
||||||
|
"hibernate.event.merge.entity_copy_observer",
|
||||||
|
"allow"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
|
||||||
* indicated by the @author tags or express copyright attribution
|
|
||||||
* statements applied by the authors. All third-party contributions are
|
|
||||||
* distributed under license by Red Hat Inc.
|
|
||||||
*
|
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
|
||||||
* Lesser General Public License, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this distribution; if not, write to:
|
|
||||||
* Free Software Foundation, Inc.
|
|
||||||
* 51 Franklin Street, Fifth Floor
|
|
||||||
* Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
package org.hibernate.jpa.event.internal.core;
|
|
||||||
|
|
||||||
import org.hibernate.event.internal.EntityCopyAllowedLoggedObserver;
|
|
||||||
import org.hibernate.event.internal.EntityCopyAllowedObserver;
|
|
||||||
import org.hibernate.event.internal.EntityCopyObserver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides {@link JpaMergeEventListener} that allows merging multiple representations
|
|
||||||
* of the same persistent entity.
|
|
||||||
*
|
|
||||||
* @author Gail Badner
|
|
||||||
*/
|
|
||||||
public class JpaEntityCopyAllowedMergeEventListener extends JpaMergeEventListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected EntityCopyObserver createEntityCopyObserver() {
|
|
||||||
return EntityCopyAllowedLoggedObserver.isDebugLoggingEnabled() ?
|
|
||||||
new EntityCopyAllowedLoggedObserver() :
|
|
||||||
new EntityCopyAllowedObserver();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -24,14 +24,11 @@
|
||||||
package org.hibernate.jpa.test.emops;
|
package org.hibernate.jpa.test.emops;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|
||||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
|
||||||
import org.hibernate.event.spi.EventType;
|
|
||||||
import org.hibernate.jpa.event.internal.core.JpaEntityCopyAllowedMergeEventListener;
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
|
||||||
|
@ -41,21 +38,19 @@ import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.Assert.assertSame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests merging multiple detached representations of the same entity using
|
* Tests merging multiple detached representations of the same entity.
|
||||||
* {@link org.hibernate.jpa.event.internal.core.JpaEntityCopyAllowedMergeEventListener}.
|
|
||||||
*
|
*
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
@TestForIssue( jiraKey = "HHH-9106")
|
@TestForIssue( jiraKey = "HHH-9106")
|
||||||
public class MergeMultipleEntityRepresentationsAllowedTest extends BaseEntityManagerFunctionalTestCase {
|
public class MergeMultipleEntityRepresentationsAllowedTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
@Override
|
protected void addConfigOptions(Map options) {
|
||||||
protected void afterEntityManagerFactoryBuilt() {
|
|
||||||
super.afterEntityManagerFactoryBuilt();
|
|
||||||
|
|
||||||
SessionFactoryImplementor sfi = entityManagerFactory().unwrap( SessionFactoryImplementor.class );
|
options.put(
|
||||||
EventListenerRegistry registry = sfi.getServiceRegistry().getService( EventListenerRegistry.class );
|
"hibernate.event.merge.entity_copy_observer",
|
||||||
registry.setListeners( EventType.MERGE, new JpaEntityCopyAllowedMergeEventListener() );
|
"allow"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue