From 6203b5da308ad45167ad0cbcc44214433b4e7f7b Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Thu, 26 Jun 2014 22:10:01 -0700 Subject: [PATCH] HHH-9106 : Merging multiple representations of the same entity (using StrategySelector) --- .../internal/StrategySelectorBuilder.java | 23 ++++++++++ .../internal/DefaultMergeEventListener.java | 34 +++++++++++--- .../EntityCopyAllowedLoggedObserver.java | 4 +- .../EntityCopyAllowedMergeEventListener.java | 41 ----------------- .../internal/EntityCopyAllowedObserver.java | 14 +++--- .../EntityCopyNotAllowedObserver.java | 3 ++ .../event/internal/MergeContext.java | 3 +- .../{internal => spi}/EntityCopyObserver.java | 2 +- .../event/internal/MergeContextTest.java | 1 + ...leEntityRepresentationsNotAllowedTest.java | 3 -- ...EntityRepresentationsOrphanDeleteTest.java | 14 +++--- ...ergeMultipleEntityRepresentationsTest.java | 13 +++--- ...paEntityCopyAllowedMergeEventListener.java | 45 ------------------- ...tipleEntityRepresentationsAllowedTest.java | 19 +++----- 14 files changed, 88 insertions(+), 131 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedMergeEventListener.java rename hibernate-core/src/main/java/org/hibernate/event/{internal => spi}/EntityCopyObserver.java (98%) delete mode 100644 hibernate-entitymanager/src/main/java/org/hibernate/jpa/event/internal/core/JpaEntityCopyAllowedMergeEventListener.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java index d118018d1e..e17512cc83 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java @@ -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.spi.JtaPlatform; 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.PersistentTableBulkIdStrategy; import org.hibernate.hql.spi.TemporaryTableBulkIdStrategy; @@ -162,6 +166,7 @@ public class StrategySelectorBuilder { addJtaPlatforms( strategySelector ); addTransactionFactories( strategySelector ); addMultiTableBulkIdStrategies( strategySelector ); + addEntityCopyObserverStrategies( strategySelector ); // apply auto-discovered registrations for ( StrategyRegistrationProvider provider : classLoaderService.loadJavaServices( StrategyRegistrationProvider.class ) ) { @@ -372,4 +377,22 @@ public class StrategySelectorBuilder { 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 + ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java index c09966bbe0..9a4bb5cec5 100755 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java @@ -31,14 +31,18 @@ import org.hibernate.HibernateException; import org.hibernate.ObjectDeletedException; import org.hibernate.StaleObjectStateException; import org.hibernate.WrongClassException; +import org.hibernate.boot.registry.selector.spi.StrategySelector; 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.CascadePoint; import org.hibernate.engine.spi.CascadingAction; import org.hibernate.engine.spi.CascadingActions; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.event.spi.EntityCopyObserver; import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.MergeEvent; import org.hibernate.event.spi.MergeEventListener; @@ -47,6 +51,7 @@ import org.hibernate.internal.CoreMessageLogger; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.LazyInitializer; +import org.hibernate.service.ServiceRegistry; import org.hibernate.type.ForeignKeyDirection; import org.hibernate.type.TypeHelper; @@ -59,15 +64,13 @@ import org.hibernate.type.TypeHelper; public class DefaultMergeEventListener extends AbstractSaveEventListener implements MergeEventListener { private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultMergeEventListener.class ); + private String entityCopyObserverStrategy; + @Override protected Map getMergeMap(Object anything) { return ( (MergeContext) anything ).invertMap(); } - protected EntityCopyObserver createEntityCopyObserver() { - return new EntityCopyNotAllowedObserver(); - } - /** * Handle the given merge event. * @@ -76,7 +79,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme * @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 ); try { 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() { + @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. * diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedLoggedObserver.java b/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedLoggedObserver.java index 279ea242b3..a4f7e65957 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedLoggedObserver.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedLoggedObserver.java @@ -35,7 +35,7 @@ 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 and provides logging of the entity copies that * that are detected. * @@ -44,6 +44,8 @@ import org.hibernate.pretty.MessageHelper; public class EntityCopyAllowedLoggedObserver extends EntityCopyAllowedObserver { 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. private Map countsByEntityName; diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedMergeEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedMergeEventListener.java deleted file mode 100644 index 74722a84f1..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedMergeEventListener.java +++ /dev/null @@ -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(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedObserver.java b/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedObserver.java index 4f12f3424d..33a947b1e9 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedObserver.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyAllowedObserver.java @@ -23,23 +23,19 @@ */ package org.hibernate.event.internal; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.Set; - +import org.hibernate.event.spi.EntityCopyObserver; 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. * * @author Gail Badner */ public class EntityCopyAllowedObserver implements EntityCopyObserver { + + public static final String SHORT_NAME = "allow"; + @Override public void entityCopyDetected( Object managedEntity, diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyNotAllowedObserver.java b/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyNotAllowedObserver.java index c647448e5c..b3d978dd48 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyNotAllowedObserver.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyNotAllowedObserver.java @@ -24,6 +24,7 @@ package org.hibernate.event.internal; import org.hibernate.AssertionFailure; +import org.hibernate.event.spi.EntityCopyObserver; import org.hibernate.event.spi.EventSource; import org.hibernate.pretty.MessageHelper; @@ -32,6 +33,8 @@ import org.hibernate.pretty.MessageHelper; */ public class EntityCopyNotAllowedObserver implements EntityCopyObserver { + public static final String SHORT_NAME = "disallow"; + @Override public void entityCopyDetected( Object managedEntity, diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/MergeContext.java b/hibernate-core/src/main/java/org/hibernate/event/internal/MergeContext.java index c3e9657057..79d95d3920 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/MergeContext.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/MergeContext.java @@ -31,6 +31,7 @@ import java.util.Set; import org.jboss.logging.Logger; +import org.hibernate.event.spi.EntityCopyObserver; import org.hibernate.event.spi.EventSource; 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 * with the same (managedEntity) value, this means that multiple entity representations * 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)} * will be called. It is up to that method to determine the property course of * action for this situation. diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyObserver.java b/hibernate-core/src/main/java/org/hibernate/event/spi/EntityCopyObserver.java similarity index 98% rename from hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyObserver.java rename to hibernate-core/src/main/java/org/hibernate/event/spi/EntityCopyObserver.java index d32b01ec80..a1286fdb7b 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/EntityCopyObserver.java +++ b/hibernate-core/src/main/java/org/hibernate/event/spi/EntityCopyObserver.java @@ -21,7 +21,7 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ -package org.hibernate.event.internal; +package org.hibernate.event.spi; import org.hibernate.event.spi.EventSource; diff --git a/hibernate-core/src/test/java/org/hibernate/event/internal/MergeContextTest.java b/hibernate-core/src/test/java/org/hibernate/event/internal/MergeContextTest.java index 887b541ff5..a2676c96fb 100644 --- a/hibernate-core/src/test/java/org/hibernate/event/internal/MergeContextTest.java +++ b/hibernate-core/src/test/java/org/hibernate/event/internal/MergeContextTest.java @@ -36,6 +36,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.hibernate.event.spi.EntityCopyObserver; import org.hibernate.event.spi.EventSource; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; diff --git a/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsNotAllowedTest.java b/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsNotAllowedTest.java index 6a02ff8e40..70a08a26fd 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsNotAllowedTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsNotAllowedTest.java @@ -29,9 +29,6 @@ import org.junit.Test; import org.hibernate.Session; 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.junit4.BaseCoreFunctionalTestCase; diff --git a/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsOrphanDeleteTest.java b/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsOrphanDeleteTest.java index 2b4f602ce1..0de5d18d1f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsOrphanDeleteTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsOrphanDeleteTest.java @@ -30,11 +30,8 @@ import org.junit.Test; import org.hibernate.Hibernate; import org.hibernate.Session; 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.cfg.Configuration; import org.hibernate.testing.FailureExpected; -import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import static org.junit.Assert.assertEquals; @@ -57,9 +54,12 @@ public class MergeMultipleEntityRepresentationsOrphanDeleteTest extends BaseCore }; } - protected void afterSessionFactoryBuilt() { - EventListenerRegistry registry = sessionFactory().getServiceRegistry().getService( EventListenerRegistry.class ); - registry.setListeners( EventType.MERGE, new EntityCopyAllowedMergeEventListener() ); + public void configure(Configuration cfg) { + super.configure( cfg ); + cfg.setProperty( + "hibernate.event.merge.entity_copy_observer", + "allow" + ); } @Test diff --git a/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsTest.java b/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsTest.java index c2d1993a50..b09171ab66 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/ops/MergeMultipleEntityRepresentationsTest.java @@ -31,9 +31,7 @@ import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.StaleObjectStateException; 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.cfg.Configuration; import org.hibernate.testing.FailureExpected; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; @@ -57,9 +55,12 @@ public class MergeMultipleEntityRepresentationsTest extends BaseCoreFunctionalTe }; } - protected void afterSessionFactoryBuilt() { - EventListenerRegistry registry = sessionFactory().getServiceRegistry().getService( EventListenerRegistry.class ); - registry.setListeners( EventType.MERGE, new EntityCopyAllowedMergeEventListener() ); + public void configure(Configuration cfg) { + super.configure( cfg ); + cfg.setProperty( + "hibernate.event.merge.entity_copy_observer", + "allow" + ); } @Test diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/event/internal/core/JpaEntityCopyAllowedMergeEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/event/internal/core/JpaEntityCopyAllowedMergeEventListener.java deleted file mode 100644 index cba9b1c6eb..0000000000 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/event/internal/core/JpaEntityCopyAllowedMergeEventListener.java +++ /dev/null @@ -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(); - } - -} diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/emops/MergeMultipleEntityRepresentationsAllowedTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/emops/MergeMultipleEntityRepresentationsAllowedTest.java index 95e0901c7a..5e65bf9f05 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/emops/MergeMultipleEntityRepresentationsAllowedTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/emops/MergeMultipleEntityRepresentationsAllowedTest.java @@ -24,14 +24,11 @@ package org.hibernate.jpa.test.emops; import java.util.List; +import java.util.Map; import javax.persistence.EntityManager; 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.testing.TestForIssue; @@ -41,21 +38,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; /** - * Tests merging multiple detached representations of the same entity using - * {@link org.hibernate.jpa.event.internal.core.JpaEntityCopyAllowedMergeEventListener}. + * Tests merging multiple detached representations of the same entity. * * @author Gail Badner */ @TestForIssue( jiraKey = "HHH-9106") public class MergeMultipleEntityRepresentationsAllowedTest extends BaseEntityManagerFunctionalTestCase { - @Override - protected void afterEntityManagerFactoryBuilt() { - super.afterEntityManagerFactoryBuilt(); + protected void addConfigOptions(Map options) { - SessionFactoryImplementor sfi = entityManagerFactory().unwrap( SessionFactoryImplementor.class ); - EventListenerRegistry registry = sfi.getServiceRegistry().getService( EventListenerRegistry.class ); - registry.setListeners( EventType.MERGE, new JpaEntityCopyAllowedMergeEventListener() ); + options.put( + "hibernate.event.merge.entity_copy_observer", + "allow" + ); } @Test