HHH-9265 - Extract EntityEntry behind a factory + interface;

HHH-9700 - Make EntityEntryFactory pluggable via EntityPersister
This commit is contained in:
Steve Ebersole 2015-03-31 14:42:40 -05:00
parent 5c4dacb83e
commit 256b2608ce
11 changed files with 96 additions and 99 deletions

View File

@ -35,27 +35,45 @@ import org.hibernate.persister.entity.EntityPersister;
/**
* Factory for the safe approach implementation of {@link org.hibernate.engine.spi.EntityEntry}.
* <p>
* <p/>
* Smarter implementations could store less state.
*
* @author Emmanuel Bernard <emmanuel@hibernate.org>
* @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() {
}
}
@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
);
}
}

View File

@ -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}.
* <p>
* 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 <emmanuel@hibernate.org>
*/
public class EntityEntryFactoryInitiator implements SessionFactoryServiceInitiator<EntityEntryFactory> {
public static final EntityEntryFactoryInitiator INSTANCE = new EntityEntryFactoryInitiator();
@Override
public EntityEntryFactory initiateService(SessionFactoryImplementor sessionFactory, SessionFactory.SessionFactoryOptions sessionFactoryOptions, ServiceRegistryImplementor registry) {
return new DefaultEntityEntryFactory();
}
@Override
public Class<EntityEntryFactory> getServiceInitiated() {
return EntityEntryFactory.class;
}
}

View File

@ -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,

View File

@ -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 <emmanuel@hibernate.org>
* @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);
}
}

View File

@ -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.
*/

View File

@ -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.

View File

@ -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 );

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;