From 256b2608ce6ac0165b939fdc07fa0da839985486 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 31 Mar 2015 14:42:40 -0500 Subject: [PATCH] HHH-9265 - Extract EntityEntry behind a factory + interface; HHH-9700 - Make EntityEntryFactory pluggable via EntityPersister --- .../internal/DefaultEntityEntryFactory.java | 54 ++++++++++++------ .../internal/EntityEntryFactoryInitiator.java | 57 ------------------- .../internal/StatefulPersistenceContext.java | 2 +- .../engine/spi/EntityEntryFactory.java | 8 +-- .../entity/AbstractEntityPersister.java | 8 +++ .../persister/entity/EntityPersister.java | 8 +++ ...andardSessionFactoryServiceInitiators.java | 2 - .../enhancement/EnhancerTestUtils.java | 35 ++++++------ .../GoofyPersisterClassProvider.java | 7 +++ .../test/legacy/CustomPersister.java | 7 +++ .../PersisterClassProviderTest.java | 7 +++ 11 files changed, 96 insertions(+), 99 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/engine/internal/EntityEntryFactoryInitiator.java diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/DefaultEntityEntryFactory.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/DefaultEntityEntryFactory.java index 7fc55c2b96..c7481dcd0d 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/DefaultEntityEntryFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/DefaultEntityEntryFactory.java @@ -35,27 +35,45 @@ import org.hibernate.persister.entity.EntityPersister; /** * Factory for the safe approach implementation of {@link org.hibernate.engine.spi.EntityEntry}. - *

+ *

* Smarter implementations could store less state. * - * @author Emmanuel Bernard + * @author Emmanuel Bernard */ public class DefaultEntityEntryFactory implements EntityEntryFactory { - @Override - public EntityEntry createEntityEntry(Status status, Object[] loadedState, Object rowId, Serializable id, Object version, LockMode lockMode, boolean existsInDatabase, EntityPersister persister, boolean disableVersionIncrement, boolean lazyPropertiesAreUnfetched, PersistenceContext persistenceContext) { + /** + * Singleton access + */ + public static final DefaultEntityEntryFactory INSTANCE = new DefaultEntityEntryFactory(); - return new MutableEntityEntry( - status, - loadedState, - rowId, - id, - version, - lockMode, - existsInDatabase, - persister, - disableVersionIncrement, - lazyPropertiesAreUnfetched, - persistenceContext - ); + private DefaultEntityEntryFactory() { } -} \ No newline at end of file + + @Override + public EntityEntry createEntityEntry( + Status status, + Object[] loadedState, + Object rowId, + Serializable id, + Object version, + LockMode lockMode, + boolean existsInDatabase, + EntityPersister persister, + boolean disableVersionIncrement, + boolean lazyPropertiesAreUnfetched, + PersistenceContext persistenceContext) { + return new MutableEntityEntry( + status, + loadedState, + rowId, + id, + version, + lockMode, + existsInDatabase, + persister, + disableVersionIncrement, + lazyPropertiesAreUnfetched, + persistenceContext + ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/EntityEntryFactoryInitiator.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/EntityEntryFactoryInitiator.java deleted file mode 100644 index ec91eef621..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/EntityEntryFactoryInitiator.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2015, 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.engine.internal; - -import org.hibernate.SessionFactory; -import org.hibernate.engine.spi.EntityEntryFactory; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.service.spi.ServiceRegistryImplementor; -import org.hibernate.service.spi.SessionFactoryServiceInitiator; - -/** - * Standard initiator for the {@link org.hibernate.engine.spi.EntityEntryFactory}. - *

- * Implementation note: - * A {@link org.hibernate.service.spi.SessionFactoryServiceInitiator} is used to allow - * overriding implementations to depend on session factory level services: - * OGM datastore provider is an example. - * TODO: make sure it is required to be a SessionFactoryServiceInitiator - * - * @author Emmanuel Bernard - */ -public class EntityEntryFactoryInitiator implements SessionFactoryServiceInitiator { - - public static final EntityEntryFactoryInitiator INSTANCE = new EntityEntryFactoryInitiator(); - - @Override - public EntityEntryFactory initiateService(SessionFactoryImplementor sessionFactory, SessionFactory.SessionFactoryOptions sessionFactoryOptions, ServiceRegistryImplementor registry) { - return new DefaultEntityEntryFactory(); - } - - @Override - public Class getServiceInitiated() { - return EntityEntryFactory.class; - } -} \ No newline at end of file diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java index 6942fe35be..bbd202fd64 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java @@ -490,7 +490,7 @@ public class StatefulPersistenceContext implements PersistenceContext { final boolean disableVersionIncrement, boolean lazyPropertiesAreUnfetched) { - EntityEntryFactory entityEntryFactory = session.getFactory().getServiceRegistry().getService( EntityEntryFactory.class ); + final EntityEntryFactory entityEntryFactory = persister.getEntityEntryFactory(); final EntityEntry e = entityEntryFactory.createEntityEntry( status, loadedState, diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/EntityEntryFactory.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/EntityEntryFactory.java index f607edd554..350a3a6d9e 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/EntityEntryFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/EntityEntryFactory.java @@ -21,21 +21,19 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ - package org.hibernate.engine.spi; import java.io.Serializable; import org.hibernate.LockMode; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.service.Service; /** * Contract to build {@link org.hibernate.engine.spi.EntityEntry} * - * @author Emmanuel Bernard + * @author Emmanuel Bernard */ -public interface EntityEntryFactory extends Service { +public interface EntityEntryFactory extends Serializable { /** * Creates {@link org.hibernate.engine.spi.EntityEntry}. @@ -52,4 +50,4 @@ public interface EntityEntryFactory extends Service { final boolean disableVersionIncrement, final boolean lazyPropertiesAreUnfetched, final PersistenceContext persistenceContext); -} \ No newline at end of file +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index cab8016d3f..ae4604aab3 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -65,6 +65,7 @@ import org.hibernate.cache.spi.entry.UnstructuredCacheEntry; import org.hibernate.dialect.lock.LockingStrategy; import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.internal.CacheHelper; +import org.hibernate.engine.internal.DefaultEntityEntryFactory; import org.hibernate.engine.internal.StatefulPersistenceContext; import org.hibernate.engine.internal.Versioning; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; @@ -72,6 +73,7 @@ import org.hibernate.engine.spi.CachedNaturalIdValueSource; import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CascadingActions; import org.hibernate.engine.spi.EntityEntry; +import org.hibernate.engine.spi.EntityEntryFactory; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; import org.hibernate.engine.spi.LoadQueryInfluencers; @@ -4811,6 +4813,12 @@ public abstract class AbstractEntityPersister return 0; } + @Override + public EntityEntryFactory getEntityEntryFactory() { + // todo : in ORM terms this should check #isMutable() and return an appropriate one. + return DefaultEntityEntryFactory.INSTANCE; + } + /** * Consolidated these onto a single helper because the 2 pieces work in tandem. */ diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java index b27b52bbf3..6c18c110b3 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java @@ -39,6 +39,7 @@ import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.cache.spi.entry.CacheEntryStructure; import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.EntityEntryFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.ValueInclusion; @@ -118,6 +119,13 @@ public interface EntityPersister extends OptimisticCacheSource, EntityDefinition // stuff that is persister-centric and/or EntityInfo-centric ~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + /** + * Get the EntityEntryFactory indicated for the entity mapped by this persister. + * + * @return The proper EntityEntryFactory. + */ + public EntityEntryFactory getEntityEntryFactory(); + /** * Returns an object that identifies the space in which identifiers of * this entity hierarchy are unique. Might be a table name, a JNDI URL, etc. diff --git a/hibernate-core/src/main/java/org/hibernate/service/internal/StandardSessionFactoryServiceInitiators.java b/hibernate-core/src/main/java/org/hibernate/service/internal/StandardSessionFactoryServiceInitiators.java index 9d01ce1f18..b8d46cfe53 100644 --- a/hibernate-core/src/main/java/org/hibernate/service/internal/StandardSessionFactoryServiceInitiators.java +++ b/hibernate-core/src/main/java/org/hibernate/service/internal/StandardSessionFactoryServiceInitiators.java @@ -27,7 +27,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.hibernate.engine.internal.EntityEntryFactoryInitiator; import org.hibernate.engine.query.spi.NativeQueryInterpreterInitiator; import org.hibernate.engine.spi.CacheInitiator; import org.hibernate.event.service.internal.EventListenerServiceInitiator; @@ -49,7 +48,6 @@ public class StandardSessionFactoryServiceInitiators { serviceInitiators.add( EventListenerServiceInitiator.INSTANCE ); serviceInitiators.add( StatisticsInitiator.INSTANCE ); serviceInitiators.add( CacheInitiator.INSTANCE ); - serviceInitiators.add( EntityEntryFactoryInitiator.INSTANCE ); serviceInitiators.add( NativeQueryInterpreterInitiator.INSTANCE ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTestUtils.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTestUtils.java index 68a6b35229..2af44a90ad 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTestUtils.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTestUtils.java @@ -23,11 +23,24 @@ */ package org.hibernate.test.bytecode.enhancement; -import com.sun.tools.classfile.ConstantPoolException; -import com.sun.tools.javap.JavapTask; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + import javassist.ClassPool; import javassist.CtClass; import javassist.LoaderClassPath; + import org.hibernate.LockMode; import org.hibernate.bytecode.enhance.spi.DefaultEnhancementContext; import org.hibernate.bytecode.enhance.spi.EnhancementContext; @@ -43,21 +56,11 @@ import org.hibernate.engine.spi.SelfDirtinessTracker; import org.hibernate.engine.spi.Status; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; + import org.hibernate.testing.junit4.BaseUnitTestCase; -import javax.tools.JavaCompiler; -import javax.tools.JavaFileObject; -import javax.tools.StandardJavaFileManager; -import javax.tools.StandardLocation; -import javax.tools.ToolProvider; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.javap.JavapTask; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -223,7 +226,7 @@ public abstract class EnhancerTestUtils extends BaseUnitTestCase { } static EntityEntry makeEntityEntry() { - return new DefaultEntityEntryFactory().createEntityEntry( + return DefaultEntityEntryFactory.INSTANCE.createEntityEntry( Status.MANAGED, null, null, diff --git a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java index f5b8bbb6c1..32ffa34fe8 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java +++ b/hibernate-core/src/test/java/org/hibernate/test/cfg/persister/GoofyPersisterClassProvider.java @@ -40,7 +40,9 @@ import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.cache.spi.entry.CacheEntryStructure; import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.internal.DefaultEntityEntryFactory; import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.EntityEntryFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.ValueInclusion; @@ -118,6 +120,11 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver { return null; } + @Override + public EntityEntryFactory getEntityEntryFactory() { + return DefaultEntityEntryFactory.INSTANCE; + } + @Override public String getRootEntityName() { return null; diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java index dfedf1dcdf..e226f29636 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java @@ -19,8 +19,10 @@ import org.hibernate.cache.spi.entry.CacheEntryStructure; import org.hibernate.cache.spi.entry.StandardCacheEntryImpl; import org.hibernate.cache.spi.entry.UnstructuredCacheEntry; import org.hibernate.cfg.NotYetImplementedException; +import org.hibernate.engine.internal.DefaultEntityEntryFactory; import org.hibernate.engine.internal.TwoPhaseLoad; import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.EntityEntryFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.ValueInclusion; @@ -73,6 +75,11 @@ public class CustomPersister implements EntityPersister { return factory; } + @Override + public EntityEntryFactory getEntityEntryFactory() { + return DefaultEntityEntryFactory.INSTANCE; + } + @Override public Class getMappedClass() { return Custom.class; diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java index 699f959f00..360db60842 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/ejb3configuration/PersisterClassProviderTest.java @@ -38,7 +38,9 @@ import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.cache.spi.entry.CacheEntryStructure; +import org.hibernate.engine.internal.DefaultEntityEntryFactory; import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.EntityEntryFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.ValueInclusion; @@ -145,6 +147,11 @@ public class PersisterClassProviderTest { return null; } + @Override + public EntityEntryFactory getEntityEntryFactory() { + return DefaultEntityEntryFactory.INSTANCE; + } + @Override public String getRootEntityName() { return null;