diff --git a/hibernate-core/src/main/java/org/hibernate/IdentifierLoadAccess.java b/hibernate-core/src/main/java/org/hibernate/IdentifierLoadAccess.java index a6e7bb613d..26f4a80967 100644 --- a/hibernate-core/src/main/java/org/hibernate/IdentifierLoadAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/IdentifierLoadAccess.java @@ -32,39 +32,43 @@ import java.io.Serializable; * @version $Revision$ */ public interface IdentifierLoadAccess { - /** - * Set the {@link LockOptions} to use when retrieving the entity. - */ - public IdentifierLoadAccess with(LockOptions lockOptions); + /** + * Set the {@link LockOptions} to use when retrieving the entity. + */ + public IdentifierLoadAccess with(LockOptions lockOptions); - /** - * Return the persistent instance of the given entity class with the given identifier, - * assuming that the instance exists. This method might return a proxied instance that - * is initialized on-demand, when a non-identifier method is accessed. - *

- * You should not use this method to determine if an instance exists (use get() - * instead). Use this only to retrieve an instance that you assume exists, where non-existence - * would be an actual error. - *

- * Due to the nature of the proxy functionality the return type of this method cannot use - * the generic type. - * - * @param theClass a persistent class - * @param id a valid identifier of an existing persistent instance of the class - * @return the persistent instance or proxy - * @throws HibernateException - */ - public Object getReference(Serializable id); + /** + * Return the persistent instance of the given entity class with the given identifier, + * assuming that the instance exists. This method might return a proxied instance that + * is initialized on-demand, when a non-identifier method is accessed.
+ *
+ * You should not use this method to determine if an instance exists (use get() instead). Use this only to + * retrieve an instance that you assume exists, where non-existence + * would be an actual error.
+ *
+ * Due to the nature of the proxy functionality the return type of this method cannot use + * the generic type. + * + * @param theClass + * a persistent class + * @param id + * a valid identifier of an existing persistent instance of the class + * @return the persistent instance or proxy + * @throws HibernateException + */ + public Object getReference(Serializable id); - /** - * Return the persistent instance of the given entity class with the given identifier, - * or null if there is no such persistent instance. (If the instance is already associated - * with the session, return that instance. This method never returns an uninitialized instance.) - * - * @param clazz a persistent class - * @param id an identifier - * @return a persistent instance or null - * @throws HibernateException - */ - public Object load(Serializable id); + /** + * Return the persistent instance of the given entity class with the given identifier, + * or null if there is no such persistent instance. (If the instance is already associated + * with the session, return that instance. This method never returns an uninitialized instance.) + * + * @param clazz + * a persistent class + * @param id + * an identifier + * @return a persistent instance or null + * @throws HibernateException + */ + public Object load(Serializable id); } diff --git a/hibernate-core/src/main/java/org/hibernate/NaturalIdLoadAccess.java b/hibernate-core/src/main/java/org/hibernate/NaturalIdLoadAccess.java index bba27abcd6..b175800a16 100644 --- a/hibernate-core/src/main/java/org/hibernate/NaturalIdLoadAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/NaturalIdLoadAccess.java @@ -23,41 +23,42 @@ */ package org.hibernate; - /** * Loads an entity by its natural identifier * * @author Eric Dalquist - * @version $Revision$ * @see org.hibernate.annotations.NaturalId */ public interface NaturalIdLoadAccess { - /** - * Set the {@link LockOptions} to use when retrieving the entity. - */ - public NaturalIdLoadAccess with(LockOptions lockOptions); + /** + * Set the {@link LockOptions} to use when retrieving the entity. + */ + public NaturalIdLoadAccess with(LockOptions lockOptions); - /** - * Add a NaturalId attribute value. - * - * @param attributeName The entity attribute name that is marked as a NaturalId - * @param value The value of the attribute - */ - public NaturalIdLoadAccess using(String attributeName, Object value); + /** + * Add a NaturalId attribute value. + * + * @param attributeName + * The entity attribute name that is marked as a NaturalId + * @param value + * The value of the attribute + */ + public NaturalIdLoadAccess using(String attributeName, Object value); - /** - * Same behavior as {@link Session#load(Class, java.io.Serializable)} - * - * @return The entity - * @throws HibernateException if the entity does not exist - */ - public Object getReference(); + /** + * Same behavior as {@link Session#load(Class, java.io.Serializable)} + * + * @return The entity + * @throws HibernateException + * if the entity does not exist + */ + public Object getReference(); - /** - * Same behavior as {@link Session#get(Class, java.io.Serializable)} - * - * @return The entity or null if it does not exist - */ - public Object load(); + /** + * Same behavior as {@link Session#get(Class, java.io.Serializable)} + * + * @return The entity or null if it does not exist + */ + public Object load(); } diff --git a/hibernate-core/src/main/java/org/hibernate/Session.java b/hibernate-core/src/main/java/org/hibernate/Session.java index ad50ed1e99..75166989f2 100644 --- a/hibernate-core/src/main/java/org/hibernate/Session.java +++ b/hibernate-core/src/main/java/org/hibernate/Session.java @@ -775,37 +775,45 @@ public interface Session extends SharedSessionContract { * Create an {@link IdentifierLoadAccess} instance to retrieve the specified entity by * primary key. * - * @param entityName The name of the entity that will be retrieved - * @throws HibernateException If the specified entity name is not found + * @param entityName + * The name of the entity that will be retrieved + * @throws HibernateException + * If the specified entity name is not found */ public IdentifierLoadAccess byId(String entityName); - + /** - * Create an {@link IdentifierLoadAccess} instance to retrieve the specified entity by - * primary key. - * - * @param entityClass The type of the entity that will be retrieved - * @throws HibernateException If the specified Class is not an entity - */ - public IdentifierLoadAccess byId(Class entityClass); - - /** - * Create an {@link NaturalIdLoadAccess} instance to retrieve the specified entity by - * its natural id. - * - * @param entityName The name of the entity that will be retrieved - * @throws HibernateException If the specified entity name is not found or if the entity does not have a natural id specified - */ - public NaturalIdLoadAccess byNaturalId(String entityName); - - /** - * Create an {@link NaturalIdLoadAccess} instance to retrieve the specified entity by - * its natural id. - * - * @param entityClass The type of the entity that will be retrieved - * @throws HibernateException If the specified Class is not an entity or if the entity does not have a natural id specified - */ - public NaturalIdLoadAccess byNaturalId(Class entityClass); + * Create an {@link IdentifierLoadAccess} instance to retrieve the specified entity by + * primary key. + * + * @param entityClass + * The type of the entity that will be retrieved + * @throws HibernateException + * If the specified Class is not an entity + */ + public IdentifierLoadAccess byId(Class entityClass); + + /** + * Create an {@link NaturalIdLoadAccess} instance to retrieve the specified entity by + * its natural id. + * + * @param entityName + * The name of the entity that will be retrieved + * @throws HibernateException + * If the specified entity name is not found or if the entity does not have a natural id specified + */ + public NaturalIdLoadAccess byNaturalId(String entityName); + + /** + * Create an {@link NaturalIdLoadAccess} instance to retrieve the specified entity by + * its natural id. + * + * @param entityClass + * The type of the entity that will be retrieved + * @throws HibernateException + * If the specified Class is not an entity or if the entity does not have a natural id specified + */ + public NaturalIdLoadAccess byNaturalId(Class entityClass); /** * Enable the named filter for this current session. diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultResolveNaturalIdEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultResolveNaturalIdEventListener.java index 4fd85511cc..f9bac82b04 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultResolveNaturalIdEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultResolveNaturalIdEventListener.java @@ -1,7 +1,7 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2010, Red Hat Inc. or third-party contributors as + * Copyright (c) 2008-2011, 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. @@ -28,598 +28,248 @@ import java.util.Map; import org.hibernate.HibernateException; import org.hibernate.LockMode; -import org.hibernate.LockOptions; -import org.hibernate.NonUniqueObjectException; -import org.hibernate.PersistentObjectException; -import org.hibernate.cache.spi.CacheKey; -import org.hibernate.cache.spi.access.SoftLock; -import org.hibernate.cache.spi.entry.CacheEntry; -import org.hibernate.engine.internal.TwoPhaseLoad; -import org.hibernate.engine.internal.Versioning; -import org.hibernate.engine.spi.EntityEntry; -import org.hibernate.engine.spi.EntityKey; -import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.engine.spi.Status; -import org.hibernate.event.service.spi.EventListenerRegistry; -import org.hibernate.event.spi.EventSource; -import org.hibernate.event.spi.EventType; -import org.hibernate.event.spi.LoadEvent; -import org.hibernate.event.spi.LoadEventListener; -import org.hibernate.event.spi.PostLoadEvent; -import org.hibernate.event.spi.PostLoadEventListener; import org.hibernate.event.spi.ResolveNaturalIdEvent; import org.hibernate.event.spi.ResolveNaturalIdEventListener; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.pretty.MessageHelper; -import org.hibernate.proxy.HibernateProxy; -import org.hibernate.proxy.LazyInitializer; import org.hibernate.tuple.StandardProperty; import org.hibernate.tuple.entity.EntityMetamodel; -import org.hibernate.type.EmbeddedComponentType; -import org.hibernate.type.Type; -import org.hibernate.type.TypeHelper; import org.jboss.logging.Logger; /** * Defines the default load event listeners used by hibernate for loading entities * in response to generated load events. - * - * @author Steve Ebersole + * + * @author Eric Dalquist */ -public class DefaultResolveNaturalIdEventListener extends AbstractLockUpgradeEventListener implements ResolveNaturalIdEventListener { +public class DefaultResolveNaturalIdEventListener extends AbstractLockUpgradeEventListener implements + ResolveNaturalIdEventListener { public static final Object REMOVED_ENTITY_MARKER = new Object(); public static final Object INCONSISTENT_RTN_CLASS_MARKER = new Object(); public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE; - private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, - DefaultResolveNaturalIdEventListener.class.getName()); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, + DefaultResolveNaturalIdEventListener.class.getName() ); - - /* (non-Javadoc) - * @see org.hibernate.event.spi.ResolveNaturalIdEventListener#onResolveNaturalId(org.hibernate.event.spi.ResolveNaturalIdEvent) - */ - @Override - public void onResolveNaturalId(ResolveNaturalIdEvent event) throws HibernateException { + /* + * (non-Javadoc) + * + * @see org.hibernate.event.spi.ResolveNaturalIdEventListener#onResolveNaturalId(org.hibernate.event.spi. + * ResolveNaturalIdEvent) + */ + @Override + public void onResolveNaturalId(ResolveNaturalIdEvent event) throws HibernateException { final SessionImplementor source = event.getSession(); EntityPersister persister = source.getFactory().getEntityPersister( event.getEntityClassName() ); if ( persister == null ) { - throw new HibernateException( - "Unable to locate persister: " + - event.getEntityClassName() - ); + throw new HibernateException( "Unable to locate persister: " + event.getEntityClassName() ); } - - //Verify that the entity has a natural id and that the properties match up with the event. + + // Verify that the entity has a natural id and that the properties match up with the event. final EntityMetamodel entityMetamodel = persister.getEntityMetamodel(); final int[] naturalIdentifierProperties = entityMetamodel.getNaturalIdentifierProperties(); - if (naturalIdentifierProperties == null || naturalIdentifierProperties.length == 0) { - throw new HibernateException(event.getEntityClassName() + " does not have a natural id"); + if ( naturalIdentifierProperties == null || naturalIdentifierProperties.length == 0 ) { + throw new HibernateException( event.getEntityClassName() + " does not have a natural id" ); } - + final Map naturalIdParams = event.getNaturalId(); - if (naturalIdentifierProperties.length != naturalIdParams.size()) { - throw new HibernateException(event.getEntityClassName() + " has " + naturalIdentifierProperties.length + " properties in its natural id but " + naturalIdParams.size() + " properties were specified: " + naturalIdParams); + if ( naturalIdentifierProperties.length != naturalIdParams.size() ) { + throw new HibernateException( event.getEntityClassName() + " has " + naturalIdentifierProperties.length + + " properties in its natural id but " + naturalIdParams.size() + " properties were specified: " + + naturalIdParams ); } - + final StandardProperty[] properties = entityMetamodel.getProperties(); - for (int idPropIdx = 0; idPropIdx < naturalIdentifierProperties.length; idPropIdx++) { - final StandardProperty property = properties[naturalIdentifierProperties[idPropIdx]]; - final String name = property.getName(); - if (!naturalIdParams.containsKey(name)) { - throw new HibernateException(event.getEntityClassName() + " natural id property " + name + " is missing from the map of natural id parameters: " + naturalIdParams); - } + for ( int idPropIdx = 0; idPropIdx < naturalIdentifierProperties.length; idPropIdx++ ) { + final StandardProperty property = properties[naturalIdentifierProperties[idPropIdx]]; + final String name = property.getName(); + if ( !naturalIdParams.containsKey( name ) ) { + throw new HibernateException( event.getEntityClassName() + " natural id property " + name + + " is missing from the map of natural id parameters: " + naturalIdParams ); + } } - - final Serializable entityId = doResolveNaturalId(event, persister); - event.setEntityId(entityId); - } + final Serializable entityId = doResolveNaturalId( event, persister ); + event.setEntityId( entityId ); + } + /** + * Coordinates the efforts to load a given entity. First, an attempt is + * made to load the entity from the session-level cache. If not found there, + * an attempt is made to locate it in second-level cache. Lastly, an + * attempt is made to load it directly from the datasource. + * + * @param event + * The load event + * @param persister + * The persister for the entity being requested for load + * @param keyToLoad + * The EntityKey representing the entity to be loaded. + * @param options + * The load options. + * @return The loaded entity, or null. + */ + protected Serializable doResolveNaturalId(final ResolveNaturalIdEvent event, final EntityPersister persister) { + if ( LOG.isTraceEnabled() ) + LOG.trace( "Attempting to resolve: " + + MessageHelper.infoString( persister, event.getNaturalId(), event.getSession().getFactory() ) ); - /** - * Coordinates the efforts to load a given entity. First, an attempt is - * made to load the entity from the session-level cache. If not found there, - * an attempt is made to locate it in second-level cache. Lastly, an - * attempt is made to load it directly from the datasource. - * - * @param event The load event - * @param persister The persister for the entity being requested for load - * @param keyToLoad The EntityKey representing the entity to be loaded. - * @param options The load options. - * @return The loaded entity, or null. - */ - protected Serializable doResolveNaturalId( - final ResolveNaturalIdEvent event, - final EntityPersister persister) { + Serializable entityId = loadFromSessionCache( event, persister ); + if ( entityId == REMOVED_ENTITY_MARKER ) { + LOG.debugf( "Load request found matching entity in context, but it is scheduled for removal; returning null" ); + return null; + } + if ( entityId == INCONSISTENT_RTN_CLASS_MARKER ) { + LOG.debugf( "Load request found matching entity in context, but the matched entity was of an inconsistent return type; returning null" ); + return null; + } + if ( entityId != null ) { + if ( LOG.isTraceEnabled() ) + LOG.trace( "Resolved object in session cache: " + + MessageHelper.infoString( persister, event.getNaturalId(), event.getSession().getFactory() ) ); + return entityId; + } - if (LOG.isTraceEnabled()) LOG.trace("Attempting to resolve: " - + MessageHelper.infoString(persister, - event.getNaturalId(), - event.getSession().getFactory())); + entityId = loadFromSecondLevelCache( event, persister ); + if ( entityId != null ) { + if ( LOG.isTraceEnabled() ) + LOG.trace( "Resolved object in second-level cache: " + + MessageHelper.infoString( persister, event.getNaturalId(), event.getSession().getFactory() ) ); + return entityId; + } - Serializable entityId = loadFromSessionCache(event, persister); - if ( entityId == REMOVED_ENTITY_MARKER ) { - LOG.debugf("Load request found matching entity in context, but it is scheduled for removal; returning null"); - return null; - } - if ( entityId == INCONSISTENT_RTN_CLASS_MARKER ) { - LOG.debugf("Load request found matching entity in context, but the matched entity was of an inconsistent return type; returning null"); - return null; - } - if ( entityId != null ) { - if (LOG.isTraceEnabled()) LOG.trace("Resolved object in session cache: " - + MessageHelper.infoString(persister, - event.getNaturalId(), - event.getSession().getFactory())); - return entityId; - } + if ( LOG.isTraceEnabled() ) + LOG.trace( "Object not resolved in any cache: " + + MessageHelper.infoString( persister, event.getNaturalId(), event.getSession().getFactory() ) ); - entityId = loadFromSecondLevelCache(event, persister); - if ( entityId != null ) { - if (LOG.isTraceEnabled()) LOG.trace("Resolved object in second-level cache: " - + MessageHelper.infoString(persister, - event.getNaturalId(), - event.getSession().getFactory())); - return entityId; - } + return loadFromDatasource( event, persister ); + } - if (LOG.isTraceEnabled()) LOG.trace("Object not resolved in any cache: " - + MessageHelper.infoString(persister, - event.getNaturalId(), - event.getSession().getFactory())); + /** + * Attempts to locate the entity in the session-level cache. + *

+ * If allowed to return nulls, then if the entity happens to be found in the session cache, we check the entity type + * for proper handling of entity hierarchies. + *

+ * If checkDeleted was set to true, then if the entity is found in the session-level cache, it's current status + * within the session cache is checked to see if it has previously been scheduled for deletion. + * + * @param event + * The load event + * @param keyToLoad + * The EntityKey representing the entity to be loaded. + * @param options + * The load options. + * @return The entity from the session-level cache, or null. + * @throws HibernateException + * Generally indicates problems applying a lock-mode. + */ + protected Serializable loadFromSessionCache(final ResolveNaturalIdEvent event, final EntityPersister persister) + throws HibernateException { + // SessionImplementor session = event.getSession(); + // Object old = session.getEntityUsingInterceptor( keyToLoad ); + // + // if ( old != null ) { + // // this object was already loaded + // EntityEntry oldEntry = session.getPersistenceContext().getEntry( old ); + // if ( options.isCheckDeleted() ) { + // Status status = oldEntry.getStatus(); + // if ( status == Status.DELETED || status == Status.GONE ) { + // return REMOVED_ENTITY_MARKER; + // } + // } + // if ( options.isAllowNulls() ) { + // final EntityPersister persister = event.getSession().getFactory().getEntityPersister( + // keyToLoad.getEntityName() ); + // if ( ! persister.isInstance( old ) ) { + // return INCONSISTENT_RTN_CLASS_MARKER; + // } + // } + // upgradeLock( old, oldEntry, event.getLockOptions(), event.getSession() ); + // } - return loadFromDatasource(event, persister); - } + return null; + } - /** - * Attempts to locate the entity in the session-level cache. - *

- * If allowed to return nulls, then if the entity happens to be found in - * the session cache, we check the entity type for proper handling - * of entity hierarchies. - *

- * If checkDeleted was set to true, then if the entity is found in the - * session-level cache, it's current status within the session cache - * is checked to see if it has previously been scheduled for deletion. - * - * @param event The load event - * @param keyToLoad The EntityKey representing the entity to be loaded. - * @param options The load options. - * @return The entity from the session-level cache, or null. - * @throws HibernateException Generally indicates problems applying a lock-mode. - */ - protected Serializable loadFromSessionCache( - final ResolveNaturalIdEvent event, - final EntityPersister persister) throws HibernateException { -// SessionImplementor session = event.getSession(); -// Object old = session.getEntityUsingInterceptor( keyToLoad ); -// -// if ( old != null ) { -// // this object was already loaded -// EntityEntry oldEntry = session.getPersistenceContext().getEntry( old ); -// if ( options.isCheckDeleted() ) { -// Status status = oldEntry.getStatus(); -// if ( status == Status.DELETED || status == Status.GONE ) { -// return REMOVED_ENTITY_MARKER; -// } -// } -// if ( options.isAllowNulls() ) { -// final EntityPersister persister = event.getSession().getFactory().getEntityPersister( keyToLoad.getEntityName() ); -// if ( ! persister.isInstance( old ) ) { -// return INCONSISTENT_RTN_CLASS_MARKER; -// } -// } -// upgradeLock( old, oldEntry, event.getLockOptions(), event.getSession() ); -// } + /** + * Attempts to load the entity from the second-level cache. + * + * @param event + * The load event + * @param persister + * The persister for the entity being requested for load + * @param options + * The load options. + * @return The entity from the second-level cache, or null. + */ + protected Serializable loadFromSecondLevelCache(final ResolveNaturalIdEvent event, final EntityPersister persister) { - return null; - } + // final SessionImplementor source = event.getSession(); + // + // final boolean useCache = persister.hasCache() + // && source.getCacheMode().isGetEnabled(); + // + // if ( useCache ) { + // + // final SessionFactoryImplementor factory = source.getFactory(); + // + // final CacheKey ck = source.generateCacheKey( + // event.getNaturalId(), + // persister.getIdentifierType(), + // persister.getRootEntityName() + // ); + // Object ce = persister.getCacheAccessStrategy().get( ck, source.getTimestamp() ); + // if ( factory.getStatistics().isStatisticsEnabled() ) { + // if ( ce == null ) { + // factory.getStatisticsImplementor().secondLevelCacheMiss( + // persister.getCacheAccessStrategy().getRegion().getName() + // ); + // } + // else { + // factory.getStatisticsImplementor().secondLevelCacheHit( + // persister.getCacheAccessStrategy().getRegion().getName() + // ); + // } + // } + // + // if ( ce != null ) { + // CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( ce, factory ); + // + // // Entity was found in second-level cache... + // return assembleCacheEntry( + // entry, + // event.getEntityId(), + // persister, + // event + // ); + // } + // } - /** - * Attempts to load the entity from the second-level cache. - * - * @param event The load event - * @param persister The persister for the entity being requested for load - * @param options The load options. - * @return The entity from the second-level cache, or null. - */ - protected Serializable loadFromSecondLevelCache( - final ResolveNaturalIdEvent event, - final EntityPersister persister) { + return null; + } -// final SessionImplementor source = event.getSession(); -// -// final boolean useCache = persister.hasCache() -// && source.getCacheMode().isGetEnabled(); -// -// if ( useCache ) { -// -// final SessionFactoryImplementor factory = source.getFactory(); -// -// final CacheKey ck = source.generateCacheKey( -// event.getNaturalId(), -// persister.getIdentifierType(), -// persister.getRootEntityName() -// ); -// Object ce = persister.getCacheAccessStrategy().get( ck, source.getTimestamp() ); -// if ( factory.getStatistics().isStatisticsEnabled() ) { -// if ( ce == null ) { -// factory.getStatisticsImplementor().secondLevelCacheMiss( -// persister.getCacheAccessStrategy().getRegion().getName() -// ); -// } -// else { -// factory.getStatisticsImplementor().secondLevelCacheHit( -// persister.getCacheAccessStrategy().getRegion().getName() -// ); -// } -// } -// -// if ( ce != null ) { -// CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( ce, factory ); -// -// // Entity was found in second-level cache... -// return assembleCacheEntry( -// entry, -// event.getEntityId(), -// persister, -// event -// ); -// } -// } + /** + * Performs the process of loading an entity from the configured + * underlying datasource. + * + * @param event + * The load event + * @param persister + * The persister for the entity being requested for load + * @param keyToLoad + * The EntityKey representing the entity to be loaded. + * @param options + * The load options. + * @return The object loaded from the datasource, or null if not found. + */ + protected Serializable loadFromDatasource(final ResolveNaturalIdEvent event, final EntityPersister persister) { + final SessionImplementor source = event.getSession(); - return null; - } - - - - /** - * Performs the process of loading an entity from the configured - * underlying datasource. - * - * @param event The load event - * @param persister The persister for the entity being requested for load - * @param keyToLoad The EntityKey representing the entity to be loaded. - * @param options The load options. - * @return The object loaded from the datasource, or null if not found. - */ - protected Serializable loadFromDatasource( - final ResolveNaturalIdEvent event, - final EntityPersister persister) { - final SessionImplementor source = event.getSession(); - - return persister.loadEntityIdByNaturalId( - event.getNaturalId(), - event.getLockOptions(), - event.getSession()); - - /* - Object entity = persister.load( - event.getEntityId(), - event.getInstanceToLoad(), - event.getLockOptions(), - source - ); - - if ( event.isAssociationFetch() && source.getFactory().getStatistics().isStatisticsEnabled() ) { - source.getFactory().getStatisticsImplementor().fetchEntity( event.getEntityClassName() ); - } - - return entity; - */ - } - - -// private void loadByDerivedIdentitySimplePkValue( -// LoadEvent event, -// LoadEventListener.LoadType options, -// EntityPersister dependentPersister, -// EmbeddedComponentType dependentIdType, -// EntityPersister parentPersister) { -// final EntityKey parentEntityKey = event.getSession().generateEntityKey( event.getEntityId(), parentPersister ); -// final Object parent = doLoad( event, parentPersister, parentEntityKey, options ); -// -// final Serializable dependent = (Serializable) dependentIdType.instantiate( parent, event.getSession() ); -// dependentIdType.setPropertyValues( dependent, new Object[] {parent}, dependentPersister.getEntityMode() ); -// final EntityKey dependentEntityKey = event.getSession().generateEntityKey( dependent, dependentPersister ); -// event.setEntityId( dependent ); -// -// event.setResult( doLoad( event, dependentPersister, dependentEntityKey, options ) ); -// } -// -// /** -// * Performs the load of an entity. -// * -// * @param event The initiating load request event -// * @param persister The persister corresponding to the entity to be loaded -// * @param keyToLoad The key of the entity to be loaded -// * @param options The defined load options -// * @return The loaded entity. -// * @throws HibernateException -// */ -// protected Object load( -// final LoadEvent event, -// final EntityPersister persister, -// final EntityKey keyToLoad, -// final LoadEventListener.LoadType options) { -// -// if ( event.getInstanceToLoad() != null ) { -// if ( event.getSession().getPersistenceContext().getEntry( event.getInstanceToLoad() ) != null ) { -// throw new PersistentObjectException( -// "attempted to load into an instance that was already associated with the session: " + -// MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) -// ); -// } -// persister.setIdentifier( event.getInstanceToLoad(), event.getEntityId(), event.getSession() ); -// } -// -// Object entity = doLoad(event, persister, keyToLoad, options); -// -// boolean isOptionalInstance = event.getInstanceToLoad() != null; -// -// if ( !options.isAllowNulls() || isOptionalInstance ) { -// if ( entity == null ) { -// event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( event.getEntityClassName(), event.getEntityId() ); -// } -// } -// -// if ( isOptionalInstance && entity != event.getInstanceToLoad() ) { -// throw new NonUniqueObjectException( event.getEntityId(), event.getEntityClassName() ); -// } -// -// return entity; -// } -// -// /** -// * Based on configured options, will either return a pre-existing proxy, -// * generate a new proxy, or perform an actual load. -// * -// * @param event The initiating load request event -// * @param persister The persister corresponding to the entity to be loaded -// * @param keyToLoad The key of the entity to be loaded -// * @param options The defined load options -// * @return The result of the proxy/load operation. -// */ -// protected Object proxyOrLoad( -// final LoadEvent event, -// final EntityPersister persister, -// final EntityKey keyToLoad, -// final LoadEventListener.LoadType options) { -// -// if (LOG.isTraceEnabled()) LOG.trace("Loading entity: " -// + MessageHelper.infoString(persister, -// event.getEntityId(), -// event.getSession().getFactory())); -// -// // this class has no proxies (so do a shortcut) -// if (!persister.hasProxy()) return load(event, persister, keyToLoad, options); -// final PersistenceContext persistenceContext = event.getSession().getPersistenceContext(); -// -// // look for a proxy -// Object proxy = persistenceContext.getProxy(keyToLoad); -// if (proxy != null) return returnNarrowedProxy(event, persister, keyToLoad, options, persistenceContext, proxy); -// if (options.isAllowProxyCreation()) return createProxyIfNecessary(event, persister, keyToLoad, options, persistenceContext); -// // return a newly loaded object -// return load(event, persister, keyToLoad, options); -// } -// -// /** -// * Given a proxy, initialize it and/or narrow it provided either -// * is necessary. -// * -// * @param event The initiating load request event -// * @param persister The persister corresponding to the entity to be loaded -// * @param keyToLoad The key of the entity to be loaded -// * @param options The defined load options -// * @param persistenceContext The originating session -// * @param proxy The proxy to narrow -// * @return The created/existing proxy -// */ -// private Object returnNarrowedProxy( -// final LoadEvent event, -// final EntityPersister persister, -// final EntityKey keyToLoad, -// final LoadEventListener.LoadType options, -// final PersistenceContext persistenceContext, -// final Object proxy) { -// LOG.trace("Entity proxy found in session cache"); -// LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer(); -// if ( li.isUnwrap() ) { -// return li.getImplementation(); -// } -// Object impl = null; -// if ( !options.isAllowProxyCreation() ) { -// impl = load( event, persister, keyToLoad, options ); -// if ( impl == null ) { -// event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( persister.getEntityName(), keyToLoad.getIdentifier()); -// } -// } -// return persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl ); -// } -// -// /** -// * If there is already a corresponding proxy associated with the -// * persistence context, return it; otherwise create a proxy, associate it -// * with the persistence context, and return the just-created proxy. -// * -// * @param event The initiating load request event -// * @param persister The persister corresponding to the entity to be loaded -// * @param keyToLoad The key of the entity to be loaded -// * @param options The defined load options -// * @param persistenceContext The originating session -// * @return The created/existing proxy -// */ -// private Object createProxyIfNecessary( -// final LoadEvent event, -// final EntityPersister persister, -// final EntityKey keyToLoad, -// final LoadEventListener.LoadType options, -// final PersistenceContext persistenceContext) { -// Object existing = persistenceContext.getEntity( keyToLoad ); -// if ( existing != null ) { -// // return existing object or initialized proxy (unless deleted) -// LOG.trace("Entity found in session cache"); -// if ( options.isCheckDeleted() ) { -// EntityEntry entry = persistenceContext.getEntry( existing ); -// Status status = entry.getStatus(); -// if ( status == Status.DELETED || status == Status.GONE ) { -// return null; -// } -// } -// return existing; -// } -// LOG.trace("Creating new proxy for entity"); -// // return new uninitialized proxy -// Object proxy = persister.createProxy(event.getEntityId(), event.getSession()); -// persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey(keyToLoad); -// persistenceContext.addProxy(keyToLoad, proxy); -// return proxy; -// } -// -// /** -// * If the class to be loaded has been configured with a cache, then lock -// * given id in that cache and then perform the load. -// * -// * @param event The initiating load request event -// * @param persister The persister corresponding to the entity to be loaded -// * @param keyToLoad The key of the entity to be loaded -// * @param options The defined load options -// * @param source The originating session -// * @return The loaded entity -// * @throws HibernateException -// */ -// protected Object lockAndLoad( -// final LoadEvent event, -// final EntityPersister persister, -// final EntityKey keyToLoad, -// final LoadEventListener.LoadType options, -// final SessionImplementor source) { -// SoftLock lock = null; -// final CacheKey ck; -// if ( persister.hasCache() ) { -// ck = source.generateCacheKey( -// event.getEntityId(), -// persister.getIdentifierType(), -// persister.getRootEntityName() -// ); -// lock = persister.getCacheAccessStrategy().lockItem( ck, null ); -// } -// else { -// ck = null; -// } -// -// Object entity; -// try { -// entity = load(event, persister, keyToLoad, options); -// } -// finally { -// if ( persister.hasCache() ) { -// persister.getCacheAccessStrategy().unlockItem( ck, lock ); -// } -// } -// -// return event.getSession().getPersistenceContext().proxyFor( persister, keyToLoad, entity ); -// } -// -// private Object assembleCacheEntry( -// final CacheEntry entry, -// final Serializable id, -// final EntityPersister persister, -// final LoadEvent event) throws HibernateException { -// -// final Object optionalObject = event.getInstanceToLoad(); -// final EventSource session = event.getSession(); -// final SessionFactoryImplementor factory = session.getFactory(); -// -// if (LOG.isTraceEnabled()) LOG.trace("Assembling entity from second-level cache: " -// + MessageHelper.infoString(persister, id, factory)); -// -// EntityPersister subclassPersister = factory.getEntityPersister( entry.getSubclass() ); -// Object result = optionalObject == null ? -// session.instantiate( subclassPersister, id ) : optionalObject; -// -// // make it circular-reference safe -// final EntityKey entityKey = session.generateEntityKey( id, subclassPersister ); -// TwoPhaseLoad.addUninitializedCachedEntity( -// entityKey, -// result, -// subclassPersister, -// LockMode.NONE, -// entry.areLazyPropertiesUnfetched(), -// entry.getVersion(), -// session -// ); -// -// Type[] types = subclassPersister.getPropertyTypes(); -// Object[] values = entry.assemble( result, id, subclassPersister, session.getInterceptor(), session ); // intializes result by side-effect -// TypeHelper.deepCopy( -// values, -// types, -// subclassPersister.getPropertyUpdateability(), -// values, -// session -// ); -// -// Object version = Versioning.getVersion( values, subclassPersister ); -// if (LOG.isTraceEnabled()) LOG.trace("Cached Version: " + version); -// -// final PersistenceContext persistenceContext = session.getPersistenceContext(); -// boolean isReadOnly = session.isDefaultReadOnly(); -// if ( persister.isMutable() ) { -// Object proxy = persistenceContext.getProxy( entityKey ); -// if ( proxy != null ) { -// // there is already a proxy for this impl -// // only set the status to read-only if the proxy is read-only -// isReadOnly = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().isReadOnly(); -// } -// } -// else { -// isReadOnly = true; -// } -// persistenceContext.addEntry( -// result, -// ( isReadOnly ? Status.READ_ONLY : Status.MANAGED ), -// values, -// null, -// id, -// version, -// LockMode.NONE, -// true, -// subclassPersister, -// false, -// entry.areLazyPropertiesUnfetched() -// ); -// subclassPersister.afterInitialize( result, entry.areLazyPropertiesUnfetched(), session ); -// persistenceContext.initializeNonLazyCollections(); -// // upgrade the lock if necessary: -// //lock(result, lockMode); -// -// //PostLoad is needed for EJB3 -// //TODO: reuse the PostLoadEvent... -// PostLoadEvent postLoadEvent = new PostLoadEvent( session ) -// .setEntity( result ) -// .setId( id ) -// .setPersister( persister ); -// -// for ( PostLoadEventListener listener : postLoadEventListeners( session ) ) { -// listener.onPostLoad( postLoadEvent ); -// } -// -// return result; -// } -// -// private Iterable postLoadEventListeners(EventSource session) { -// return session -// .getFactory() -// .getServiceRegistry() -// .getService( EventListenerRegistry.class ) -// .getEventListenerGroup( EventType.POST_LOAD ) -// .listeners(); -// } + return persister.loadEntityIdByNaturalId( event.getNaturalId(), event.getLockOptions(), event.getSession() ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerRegistryImpl.java index 1084292f5b..6735e28e78 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerRegistryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerRegistryImpl.java @@ -247,12 +247,12 @@ public class EventListenerRegistryImpl implements EventListenerRegistry { workMap ); - // resolve natural-id listeners - prepareListeners( - RESOLVE_NATURAL_ID, - new DefaultResolveNaturalIdEventListener(), - workMap - ); + // resolve natural-id listeners + prepareListeners( + RESOLVE_NATURAL_ID, + new DefaultResolveNaturalIdEventListener(), + workMap + ); // load-collection listeners prepareListeners( diff --git a/hibernate-core/src/main/java/org/hibernate/event/spi/EventType.java b/hibernate-core/src/main/java/org/hibernate/event/spi/EventType.java index bc01b93ccb..aa63f0cc3b 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/spi/EventType.java +++ b/hibernate-core/src/main/java/org/hibernate/event/spi/EventType.java @@ -40,8 +40,8 @@ import org.hibernate.HibernateException; public class EventType { public static final EventType LOAD = new EventType( "load", LoadEventListener.class ); - public static final EventType RESOLVE_NATURAL_ID - = new EventType( "resolve-natural-id", ResolveNaturalIdEventListener.class ); + public static final EventType RESOLVE_NATURAL_ID + = new EventType( "resolve-natural-id", ResolveNaturalIdEventListener.class ); public static final EventType INIT_COLLECTION = new EventType( "load-collection", InitializeCollectionEventListener.class ); diff --git a/hibernate-core/src/main/java/org/hibernate/event/spi/ResolveNaturalIdEvent.java b/hibernate-core/src/main/java/org/hibernate/event/spi/ResolveNaturalIdEvent.java index d8704dc80b..7531c1a18b 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/spi/ResolveNaturalIdEvent.java +++ b/hibernate-core/src/main/java/org/hibernate/event/spi/ResolveNaturalIdEvent.java @@ -31,9 +31,9 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; /** - * Defines an event class for the resolving of an entity id from the entity's natural-id - * - * @author Steve Ebersole + * Defines an event class for the resolving of an entity id from the entity's natural-id + * + * @author Eric Dalquist */ public class ResolveNaturalIdEvent extends AbstractEvent { public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE; @@ -44,29 +44,30 @@ public class ResolveNaturalIdEvent extends AbstractEvent { private Serializable entityId; public ResolveNaturalIdEvent(Map naturalId, String entityClassName, EventSource source) { - this(naturalId, entityClassName, new LockOptions(), source); + this( naturalId, entityClassName, new LockOptions(), source ); } - - public ResolveNaturalIdEvent(Map naturalId, String entityClassName, LockOptions lockOptions, EventSource source) { - super(source); + + public ResolveNaturalIdEvent(Map naturalId, String entityClassName, LockOptions lockOptions, + EventSource source) { + super( source ); if ( naturalId == null || naturalId.isEmpty() ) { - throw new IllegalArgumentException("id to load is required for loading"); + throw new IllegalArgumentException( "id to load is required for loading" ); } - if ( lockOptions.getLockMode() == LockMode.WRITE ) { - throw new IllegalArgumentException("Invalid lock mode for loading"); - } - else if ( lockOptions.getLockMode() == null ) { - lockOptions.setLockMode(DEFAULT_LOCK_MODE); - } + if ( lockOptions.getLockMode() == LockMode.WRITE ) { + throw new IllegalArgumentException( "Invalid lock mode for loading" ); + } + else if ( lockOptions.getLockMode() == null ) { + lockOptions.setLockMode( DEFAULT_LOCK_MODE ); + } this.naturalId = naturalId; this.entityClassName = entityClassName; } public Map getNaturalId() { - return Collections.unmodifiableMap(naturalId); + return Collections.unmodifiableMap( naturalId ); } public void setNaturalId(Map naturalId) { @@ -89,11 +90,11 @@ public class ResolveNaturalIdEvent extends AbstractEvent { this.entityId = entityId; } - public LockOptions getLockOptions() { - return lockOptions; - } + public LockOptions getLockOptions() { + return lockOptions; + } - public void setLockOptions(LockOptions lockOptions) { - this.lockOptions = lockOptions; - } + public void setLockOptions(LockOptions lockOptions) { + this.lockOptions = lockOptions; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/event/spi/ResolveNaturalIdEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/spi/ResolveNaturalIdEventListener.java index a1dc43e3da..4939cccb84 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/spi/ResolveNaturalIdEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/spi/ResolveNaturalIdEventListener.java @@ -29,17 +29,18 @@ import org.hibernate.HibernateException; /** * Defines the contract for handling of resolve natural id events generated from a session. - * - * @author Steve Ebersole + * + * @author Eric Dalquist */ public interface ResolveNaturalIdEventListener extends Serializable { - /** + /** * Handle the given resolve natural id event. - * - * @param event The resolve natural id event to be handled. - * @throws HibernateException - */ + * + * @param event + * The resolve natural id event to be handled. + * @throws HibernateException + */ public void onResolveNaturalId(ResolveNaturalIdEvent event) throws HibernateException; } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java index 4face8d2ed..2f4c2dafd8 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -844,11 +844,11 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc } public Object load(Class entityClass, Serializable id) throws HibernateException { - return this.byId(entityClass).getReference(id); + return this.byId(entityClass).getReference(id); } public Object load(String entityName, Serializable id) throws HibernateException { - return this.byId(entityName).getReference(id); + return this.byId(entityName).getReference(id); } public Object get(Class entityClass, Serializable id) throws HibernateException { @@ -891,70 +891,58 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc } public Object load(Class entityClass, Serializable id, LockMode lockMode) throws HibernateException { - return this.byId(entityClass).with(lockMode).getReference(id); + return this.byId( entityClass ).with( lockMode ).getReference( id ); } public Object load(Class entityClass, Serializable id, LockOptions lockOptions) throws HibernateException { - return this.byId(entityClass).with(lockOptions).getReference(id); + return this.byId( entityClass ).with( lockOptions ).getReference( id ); } public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException { - return this.byId(entityName).with(lockMode).getReference(id); + return this.byId( entityName ).with( lockMode ).getReference( id ); } public Object load(String entityName, Serializable id, LockOptions lockOptions) throws HibernateException { - return this.byId(entityName).with(lockOptions).getReference(id); + return this.byId( entityName ).with( lockOptions ).getReference( id ); } public Object get(Class entityClass, Serializable id, LockMode lockMode) throws HibernateException { - return this.byId(entityClass).with(lockMode).load(id); + return this.byId( entityClass ).with( lockMode ).load( id ); } public Object get(Class entityClass, Serializable id, LockOptions lockOptions) throws HibernateException { - return this.byId(entityClass).with(lockOptions).load(id); + return this.byId( entityClass ).with( lockOptions ).load( id ); } public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException { - return this.byId(entityName).with(lockMode).load(id); + return this.byId( entityName ).with( lockMode ).load( id ); } public Object get(String entityName, Serializable id, LockOptions lockOptions) throws HibernateException { - return this.byId(entityName).with(lockOptions).load(id); + return this.byId( entityName ).with( lockOptions ).load( id ); } - /* (non-Javadoc) - * @see org.hibernate.Session#byId(java.lang.String) - */ - @Override - public IdentifierLoadAccessImpl byId(String entityName) { - return new IdentifierLoadAccessImpl(entityName, Object.class); - } + @Override + public IdentifierLoadAccessImpl byId(String entityName) { + return new IdentifierLoadAccessImpl( entityName, Object.class ); + } - /* (non-Javadoc) - * @see org.hibernate.Session#byId(java.lang.Class) - */ - @Override - public IdentifierLoadAccessImpl byId(Class entityClass) { - return new IdentifierLoadAccessImpl(entityClass.getName(), entityClass); - } + @Override + public IdentifierLoadAccessImpl byId(Class entityClass) { + return new IdentifierLoadAccessImpl( entityClass.getName(), entityClass ); + } - /* (non-Javadoc) - * @see org.hibernate.Session#byNaturalId(java.lang.String) - */ - @Override - public NaturalIdLoadAccess byNaturalId(String entityName) { - return new NaturalIdLoadAccessImpl(entityName, Object.class); - } + @Override + public NaturalIdLoadAccess byNaturalId(String entityName) { + return new NaturalIdLoadAccessImpl( entityName, Object.class ); + } - /* (non-Javadoc) - * @see org.hibernate.Session#byNaturalId(java.lang.Class) - */ - @Override - public NaturalIdLoadAccess byNaturalId(Class entityClass) { - return new NaturalIdLoadAccessImpl(entityClass.getName(), entityClass); - } + @Override + public NaturalIdLoadAccess byNaturalId(Class entityClass) { + return new NaturalIdLoadAccessImpl( entityClass.getName(), entityClass ); + } - private void fireLoad(LoadEvent event, LoadType loadType) { + private void fireLoad(LoadEvent event, LoadType loadType) { errorIfClosed(); checkTransactionSynchStatus(); for ( LoadEventListener listener : listeners( EventType.LOAD ) ) { @@ -962,13 +950,13 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc } } - private void fireResolveNaturalId(ResolveNaturalIdEvent event) { - errorIfClosed(); - checkTransactionSynchStatus(); - for ( ResolveNaturalIdEventListener listener : listeners( EventType.RESOLVE_NATURAL_ID ) ) { - listener.onResolveNaturalId(event); - } - } + private void fireResolveNaturalId(ResolveNaturalIdEvent event) { + errorIfClosed(); + checkTransactionSynchStatus(); + for ( ResolveNaturalIdEventListener listener : listeners( EventType.RESOLVE_NATURAL_ID ) ) { + listener.onResolveNaturalId( event ); + } + } // refresh() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2180,157 +2168,132 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc } } - private class IdentifierLoadAccessImpl implements IdentifierLoadAccess { - private final String entityName; - private final Class entityClass; - private LockOptions lockOptions; - - /** - */ - private IdentifierLoadAccessImpl(String entityName, Class entityClass) { - this.entityName = entityName; - this.entityClass = entityClass; - } + private class IdentifierLoadAccessImpl implements IdentifierLoadAccess { + private final String entityName; + private final Class entityClass; + private LockOptions lockOptions; - /* (non-Javadoc) - * @see org.hibernate.IdentifierLoadAccess#with(org.hibernate.LockOptions) - */ - @Override - public final IdentifierLoadAccessImpl with(LockOptions lockOptions) { - this.lockOptions = lockOptions; - return this; - } + private IdentifierLoadAccessImpl(String entityName, Class entityClass) { + this.entityName = entityName; + this.entityClass = entityClass; + } - /** + @Override + public final IdentifierLoadAccessImpl with(LockOptions lockOptions) { + this.lockOptions = lockOptions; + return this; + } + + /** * Support for legacy {@link Session#load(Class, Serializable, LockMode)} and {@link Session#load(String, Serializable, LockMode) * @deprecated */ - @Deprecated - public final IdentifierLoadAccessImpl with(LockMode lockMode) { - this.lockOptions = new LockOptions(); - this.lockOptions.setLockMode(lockMode); - return this; - } + @Deprecated + public final IdentifierLoadAccessImpl with(LockMode lockMode) { + this.lockOptions = new LockOptions(); + this.lockOptions.setLockMode( lockMode ); + return this; + } - /* (non-Javadoc) - * @see org.hibernate.IdentifierLoadAccess#getReference(java.io.Serializable) - */ - @Override - public final Object getReference(Serializable id) { - if (this.lockOptions != null) { - LoadEvent event = new LoadEvent(id, entityName, lockOptions, SessionImpl.this); - fireLoad( event, LoadEventListener.LOAD ); - return event.getResult(); - } - - LoadEvent event = new LoadEvent(id, entityName, false, SessionImpl.this); - boolean success = false; - try { - fireLoad( event, LoadEventListener.LOAD ); - if ( event.getResult() == null ) { - getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id ); - } - success = true; - return event.getResult(); - } - finally { - afterOperation(success); - } - } + @Override + public final Object getReference(Serializable id) { + if ( this.lockOptions != null ) { + LoadEvent event = new LoadEvent( id, entityName, lockOptions, SessionImpl.this ); + fireLoad( event, LoadEventListener.LOAD ); + return event.getResult(); + } - /* (non-Javadoc) - * @see org.hibernate.IdentifierLoadAccess#load(java.io.Serializable) - */ - @Override - public final Object load(Serializable id) { - if (this.lockOptions != null) { - LoadEvent event = new LoadEvent(id, entityName, lockOptions, SessionImpl.this); - fireLoad( event, LoadEventListener.GET ); - return event.getResult(); - } - - LoadEvent event = new LoadEvent(id, entityName, false, SessionImpl.this); - boolean success = false; - try { - fireLoad(event, LoadEventListener.GET); - success = true; - return event.getResult(); - } - finally { - afterOperation(success); - } - } + LoadEvent event = new LoadEvent( id, entityName, false, SessionImpl.this ); + boolean success = false; + try { + fireLoad( event, LoadEventListener.LOAD ); + if ( event.getResult() == null ) { + getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id ); + } + success = true; + return event.getResult(); + } + finally { + afterOperation( success ); + } + } + + @Override + public final Object load(Serializable id) { + if ( this.lockOptions != null ) { + LoadEvent event = new LoadEvent( id, entityName, lockOptions, SessionImpl.this ); + fireLoad( event, LoadEventListener.GET ); + return event.getResult(); + } + + LoadEvent event = new LoadEvent( id, entityName, false, SessionImpl.this ); + boolean success = false; + try { + fireLoad( event, LoadEventListener.GET ); + success = true; + return event.getResult(); + } + finally { + afterOperation( success ); + } + } } - - private class NaturalIdLoadAccessImpl implements NaturalIdLoadAccess { - private final String entityName; - private final Class entityClass; - private final Map naturalIdParameters = new LinkedHashMap(); - private LockOptions lockOptions; - - /** - * Note that the specified entity MUST be castable using {@link Class#cast(Object)} - * on the specified entityClass - */ - private NaturalIdLoadAccessImpl(String entityName, Class entityClass) { - this.entityName = entityName; - this.entityClass = entityClass; - } - /* (non-Javadoc) - * @see org.hibernate.IdentifierLoadAccess#with(org.hibernate.LockOptions) - */ - @Override - public final NaturalIdLoadAccess with(LockOptions lockOptions) { - this.lockOptions = lockOptions; - return this; - } - - /* (non-Javadoc) - * @see org.hibernate.NaturalIdLoadAccess#using(java.lang.String, java.lang.Object) - */ - @Override - public NaturalIdLoadAccess using(String attributeName, Object value) { - naturalIdParameters.put(attributeName, value); - return this; - } - - protected Serializable resolveNaturalId() { - final ResolveNaturalIdEvent event = new ResolveNaturalIdEvent(naturalIdParameters, entityName, SessionImpl.this); - fireResolveNaturalId(event); - return event.getEntityId(); - } - - protected IdentifierLoadAccess getIdentifierLoadAccess() { - final IdentifierLoadAccessImpl identifierLoadAccess = new SessionImpl.IdentifierLoadAccessImpl(entityName, entityClass); - if (this.lockOptions != null) { - identifierLoadAccess.with(lockOptions); - } - return identifierLoadAccess; - } + private class NaturalIdLoadAccessImpl implements NaturalIdLoadAccess { + private final String entityName; + private final Class entityClass; + private final Map naturalIdParameters = new LinkedHashMap(); + private LockOptions lockOptions; - /* (non-Javadoc) - * @see org.hibernate.NaturalIdLoadAccess#getReference() - */ - @Override - public final Object getReference() { - final Serializable entityId = resolveNaturalId(); - if (entityId == null) { - return null; - } - return this.getIdentifierLoadAccess().getReference(entityId); - } + private NaturalIdLoadAccessImpl(String entityName, Class entityClass) { + this.entityName = entityName; + this.entityClass = entityClass; + } - /* (non-Javadoc) - * @see org.hibernate.NaturalIdLoadAccess#load() - */ - @Override - public final Object load() { - final Serializable entityId = resolveNaturalId(); - if (entityId == null) { - return null; - } - return this.getIdentifierLoadAccess().load(entityId); - } - } + @Override + public final NaturalIdLoadAccess with(LockOptions lockOptions) { + this.lockOptions = lockOptions; + return this; + } + + @Override + public NaturalIdLoadAccess using(String attributeName, Object value) { + naturalIdParameters.put( attributeName, value ); + return this; + } + + protected Serializable resolveNaturalId() { + final ResolveNaturalIdEvent event = new ResolveNaturalIdEvent( naturalIdParameters, entityName, + SessionImpl.this ); + fireResolveNaturalId( event ); + return event.getEntityId(); + } + + protected IdentifierLoadAccess getIdentifierLoadAccess() { + final IdentifierLoadAccessImpl identifierLoadAccess = new SessionImpl.IdentifierLoadAccessImpl( + entityName, entityClass ); + if ( this.lockOptions != null ) { + identifierLoadAccess.with( lockOptions ); + } + return identifierLoadAccess; + } + + @Override + public final Object getReference() { + final Serializable entityId = resolveNaturalId(); + if ( entityId == null ) { + return null; + } + return this.getIdentifierLoadAccess().getReference( entityId ); + } + + @Override + public final Object load() { + final Serializable entityId = resolveNaturalId(); + if ( entityId == null ) { + return null; + } + return this.getIdentifierLoadAccess().load( entityId ); + } + } } 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 9a43ddabd6..59180165da 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 @@ -3390,7 +3390,7 @@ public abstract class AbstractEntityPersister if (sqlUpdateGeneratedValuesSelectString != null) LOG.debugf("Update-generated property select: %s", sqlUpdateGeneratedValuesSelectString); if (sqlEntityIdByNaturalIdString != null) LOG.debugf("Id by Natural Id: %s", - sqlEntityIdByNaturalIdString); + sqlEntityIdByNaturalIdString); } } @@ -4503,103 +4503,95 @@ public abstract class AbstractEntityPersister } } - /* (non-Javadoc) - * @see org.hibernate.persister.entity.EntityPersister#loadEntityIdByNaturalId(java.util.Map, org.hibernate.engine.spi.SessionImplementor) - */ - @Override - public Serializable loadEntityIdByNaturalId(Map naturalIdParameters, LockOptions lockOptions, SessionImplementor session) { - if ( !hasNaturalIdentifier() ) { - throw new MappingException( "persistent class did not define a natural-id : " + MessageHelper.infoString( this ) ); - } - if (LOG.isTraceEnabled()) LOG.trace("Getting entity id for natural-id for: " - + MessageHelper.infoString(this, naturalIdParameters, getFactory())); + @Override + public Serializable loadEntityIdByNaturalId(Map naturalIdParameters, LockOptions lockOptions, + SessionImplementor session) { + if ( !hasNaturalIdentifier() ) { + throw new MappingException( "persistent class did not define a natural-id : " + + MessageHelper.infoString( this ) ); + } + if ( LOG.isTraceEnabled() ) + LOG.trace( "Getting entity id for natural-id for: " + + MessageHelper.infoString( this, naturalIdParameters, getFactory() ) ); - try { - PreparedStatement ps = session.getTransactionCoordinator() - .getJdbcCoordinator() - .getStatementPreparer() - .prepareStatement( sqlEntityIdByNaturalIdString ); - try { - int positions = 1; - final int[] naturalIdPropertyIndexes = this.getNaturalIdentifierProperties(); - for (int propIdx = 0; propIdx < naturalIdPropertyIndexes.length; propIdx++) { - final int naturalIdIdx = naturalIdPropertyIndexes[propIdx]; - - final StandardProperty[] properties = entityMetamodel.getProperties(); - final StandardProperty property = properties[naturalIdIdx]; - - final Object value = naturalIdParameters.get(property.getName()); - - //TODO am I setting the positions var correctly here? - final Type propertyType = property.getType(); - propertyType.nullSafeSet( ps, value, positions, session ); - positions += propertyType.getColumnSpan(session.getFactory()); - } - ResultSet rs = ps.executeQuery(); - try { - //if there is no resulting row, return null - if ( !rs.next() ) { - return null; - } + try { + PreparedStatement ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer() + .prepareStatement( sqlEntityIdByNaturalIdString ); + try { + int positions = 1; + final int[] naturalIdPropertyIndexes = this.getNaturalIdentifierProperties(); + for ( int propIdx = 0; propIdx < naturalIdPropertyIndexes.length; propIdx++ ) { + final int naturalIdIdx = naturalIdPropertyIndexes[propIdx]; - //entity ID has to be serializable right? - return (Serializable) getIdentifierType().hydrate(rs, getIdentifierAliases(), session, null); - } - finally { - rs.close(); - } - } - finally { - ps.close(); - } - } - catch ( SQLException e ) { - throw getFactory().getSQLExceptionHelper().convert( - e, - "could not retrieve entity id: " + MessageHelper.infoString( this, naturalIdParameters, getFactory() ), - sqlEntityIdByNaturalIdString - ); - } - } + final StandardProperty[] properties = entityMetamodel.getProperties(); + final StandardProperty property = properties[naturalIdIdx]; - /** - * @return - */ - private String generateEntityIdByNaturalIdSql() { - Select select = new Select( getFactory().getDialect() ); - if ( getFactory().getSettings().isCommentsEnabled() ) { - select.setComment( "get current natural-id->entity-id state " + getEntityName() ); - } - - final String rootAlias = getRootAlias(); - - select.setSelectClause( identifierSelectFragment(rootAlias, "") ); - select.setFromClause( fromTableFragment( rootAlias ) + fromJoinFragment( rootAlias, true, false ) ); - - final StringBuilder whereClause = new StringBuilder(); - final int[] propertyTableNumbers = getPropertyTableNumbers(); - final int[] naturalIdPropertyIndexes = this.getNaturalIdentifierProperties(); - for (int propIdx = 0; propIdx < naturalIdPropertyIndexes.length; propIdx++) { - if (propIdx > 0) { - whereClause.append(" and "); - } - - final int naturalIdIdx = naturalIdPropertyIndexes[propIdx]; - final String tableAlias = generateTableAlias( rootAlias, propertyTableNumbers[naturalIdIdx] ); - - final String[] propertyColumnNames = getPropertyColumnNames(naturalIdIdx); - final String[] aliasedPropertyColumns = StringHelper.qualify( rootAlias, propertyColumnNames ); - - whereClause.append( StringHelper.join( "=? and ", aliasedPropertyColumns ) ).append( "=?" ); - } - - whereClause.append( whereJoinFragment( getRootAlias(), true, false ) ); - - String sql = select.setOuterJoins( "", "" ) - .setWhereClause( whereClause.toString() ) - .toStatementString(); - return sql; - } + final Object value = naturalIdParameters.get( property.getName() ); + + final Type propertyType = property.getType(); + propertyType.nullSafeSet( ps, value, positions, session ); + positions += propertyType.getColumnSpan( session.getFactory() ); + } + ResultSet rs = ps.executeQuery(); + try { + // if there is no resulting row, return null + if ( !rs.next() ) { + return null; + } + + // entity ID has to be serializable right? + return (Serializable) getIdentifierType().hydrate( rs, getIdentifierAliases(), session, null ); + } + finally { + rs.close(); + } + } + finally { + ps.close(); + } + } + catch ( SQLException e ) { + throw getFactory().getSQLExceptionHelper().convert( + e, + "could not retrieve entity id: " + + MessageHelper.infoString( this, naturalIdParameters, getFactory() ), + sqlEntityIdByNaturalIdString ); + } + } + + private String generateEntityIdByNaturalIdSql() { + Select select = new Select( getFactory().getDialect() ); + if ( getFactory().getSettings().isCommentsEnabled() ) { + select.setComment( "get current natural-id->entity-id state " + getEntityName() ); + } + + final String rootAlias = getRootAlias(); + + select.setSelectClause( identifierSelectFragment( rootAlias, "" ) ); + select.setFromClause( fromTableFragment( rootAlias ) + fromJoinFragment( rootAlias, true, false ) ); + + final StringBuilder whereClause = new StringBuilder(); + final int[] propertyTableNumbers = getPropertyTableNumbers(); + final int[] naturalIdPropertyIndexes = this.getNaturalIdentifierProperties(); + for ( int propIdx = 0; propIdx < naturalIdPropertyIndexes.length; propIdx++ ) { + if ( propIdx > 0 ) { + whereClause.append( " and " ); + } + + final int naturalIdIdx = naturalIdPropertyIndexes[propIdx]; + final String tableAlias = generateTableAlias( rootAlias, propertyTableNumbers[naturalIdIdx] ); + + final String[] propertyColumnNames = getPropertyColumnNames( naturalIdIdx ); + final String[] aliasedPropertyColumns = StringHelper.qualify( rootAlias, propertyColumnNames ); + + whereClause.append( StringHelper.join( "=? and ", aliasedPropertyColumns ) ).append( "=?" ); + } + + whereClause.append( whereJoinFragment( getRootAlias(), true, false ) ); + + String sql = select.setOuterJoins( "", "" ).setWhereClause( whereClause.toString() ).toStatementString(); + return sql; + } protected String concretePropertySelectFragmentSansLeadingComma(String alias, boolean[] include) { String concretePropertySelectFragment = concretePropertySelectFragment( alias, include ); 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 6b9ac1fa9e..86f353adfb 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 @@ -320,11 +320,12 @@ public interface EntityPersister extends OptimisticCacheSource { * @return True if the entity has properties mapped as lazy; false otherwise. */ public boolean hasLazyProperties(); - + /** * Load the id for the entity based on the natural id. */ - public Serializable loadEntityIdByNaturalId(Map naturalIdParameters, LockOptions lockOptions, SessionImplementor session); + public Serializable loadEntityIdByNaturalId(Map naturalIdParameters, LockOptions lockOptions, + SessionImplementor session); /** * Load an instance of the persistent class. diff --git a/hibernate-core/src/matrix/java/org/hibernate/test/jpa/naturalid/ImmutableNaturalIdTest.java b/hibernate-core/src/matrix/java/org/hibernate/test/jpa/naturalid/ImmutableNaturalIdTest.java index 3d12299759..8e25e10517 100644 --- a/hibernate-core/src/matrix/java/org/hibernate/test/jpa/naturalid/ImmutableNaturalIdTest.java +++ b/hibernate-core/src/matrix/java/org/hibernate/test/jpa/naturalid/ImmutableNaturalIdTest.java @@ -105,66 +105,61 @@ public class ImmutableNaturalIdTest extends AbstractJPATest { t.commit(); s.close(); } - + @Test + public void testNaturalIdLoadAccessCache() { + Session s = openSession(); + s.beginTransaction(); + User u = new User( "steve", "superSecret" ); + s.persist( u ); + s.getTransaction().commit(); + s.close(); - @Test - public void testNaturalIdLoadAccessCache() { - Session s = openSession(); - s.beginTransaction(); - User u = new User( "steve", "superSecret" ); - s.persist( u ); - s.getTransaction().commit(); - s.close(); + sessionFactory().getStatistics().clear(); - sessionFactory().getStatistics().clear(); -// sessionFactory().getStatistics().logSummary(); + s = openSession(); + s.beginTransaction(); + u = (User) s.byNaturalId( User.class ).using( "userName", "steve" ).load(); + assertNotNull( u ); + s.getTransaction().commit(); + s.close(); - s = openSession(); - s.beginTransaction(); - u = ( User )s.byNaturalId(User.class).using( "userName", "steve" ).load(); - assertNotNull( u ); - s.getTransaction().commit(); - s.close(); - -// sessionFactory().getStatistics().logSummary(); + assertEquals( 1, sessionFactory().getStatistics().getEntityLoadCount() ); + assertEquals( 0, sessionFactory().getStatistics().getSecondLevelCacheMissCount() ); + assertEquals( 0, sessionFactory().getStatistics().getSecondLevelCacheHitCount() ); + assertEquals( 0, sessionFactory().getStatistics().getSecondLevelCachePutCount() ); + assertEquals( 0, sessionFactory().getStatistics().getQueryExecutionCount() ); + assertEquals( 0, sessionFactory().getStatistics().getQueryCacheHitCount() ); + assertEquals( 0, sessionFactory().getStatistics().getQueryCachePutCount() ); - assertEquals( 1, sessionFactory().getStatistics().getEntityLoadCount() ); - assertEquals( 0, sessionFactory().getStatistics().getSecondLevelCacheMissCount() ); - assertEquals( 0, sessionFactory().getStatistics().getSecondLevelCacheHitCount() ); - assertEquals( 0, sessionFactory().getStatistics().getSecondLevelCachePutCount() ); - assertEquals( 0, sessionFactory().getStatistics().getQueryExecutionCount() ); - assertEquals( 0, sessionFactory().getStatistics().getQueryCacheHitCount() ); - assertEquals( 0, sessionFactory().getStatistics().getQueryCachePutCount() ); + s = openSession(); + s.beginTransaction(); + User v = new User( "gavin", "supsup" ); + s.persist( v ); + s.getTransaction().commit(); + s.close(); - s = openSession(); - s.beginTransaction(); - User v = new User( "gavin", "supsup" ); - s.persist( v ); - s.getTransaction().commit(); - s.close(); + sessionFactory().getStatistics().clear(); - sessionFactory().getStatistics().clear(); + s = openSession(); + s.beginTransaction(); + u = (User) s.byNaturalId( User.class ).using( "userName", "steve" ).load(); + assertNotNull( u ); + assertEquals( sessionFactory().getStatistics().getQueryExecutionCount(), 0 ); + assertEquals( sessionFactory().getStatistics().getQueryCacheHitCount(), 0 ); + u = (User) s.byNaturalId( User.class ).using( "userName", "steve" ).load(); + assertNotNull( u ); + assertEquals( sessionFactory().getStatistics().getQueryExecutionCount(), 0 ); + assertEquals( sessionFactory().getStatistics().getQueryCacheHitCount(), 0 ); + s.getTransaction().commit(); + s.close(); - s = openSession(); - s.beginTransaction(); - u = ( User )s.byNaturalId(User.class).using( "userName", "steve" ).load(); - assertNotNull( u ); - assertEquals( sessionFactory().getStatistics().getQueryExecutionCount(), 0 ); - assertEquals( sessionFactory().getStatistics().getQueryCacheHitCount(), 0 ); - u = ( User )s.byNaturalId(User.class).using( "userName", "steve" ).load(); - assertNotNull( u ); - assertEquals( sessionFactory().getStatistics().getQueryExecutionCount(), 0 ); - assertEquals( sessionFactory().getStatistics().getQueryCacheHitCount(), 0 ); - s.getTransaction().commit(); - s.close(); - - s = openSession(); - s.beginTransaction(); - s.createQuery( "delete User" ).executeUpdate(); - s.getTransaction().commit(); - s.close(); - } + s = openSession(); + s.beginTransaction(); + s.createQuery( "delete User" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + } @Test public void testNaturalIdCache() { 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 113d676780..1c02fb18cb 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 @@ -238,14 +238,14 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver { public Object[] getNaturalIdentifierSnapshot(Serializable id, SessionImplementor session) { return new Object[0]; } - - @Override - public Serializable loadEntityIdByNaturalId(Map naturalIdParameters, LockOptions lockOptions, - SessionImplementor session) { - return null; - } - @Override + @Override + public Serializable loadEntityIdByNaturalId(Map naturalIdParameters, LockOptions lockOptions, + SessionImplementor session) { + return null; + } + + @Override public IdentifierGenerator getIdentifierGenerator() { 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 d70ea99c0a..ff3254d1c0 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 @@ -601,14 +601,14 @@ public class CustomPersister implements EntityPersister { public Object[] getNaturalIdentifierSnapshot(Serializable id, SessionImplementor session) throws HibernateException { return null; } - - @Override - public Serializable loadEntityIdByNaturalId(Map naturalIdParameters, LockOptions lockOptions, - SessionImplementor session) { - return null; - } - @Override + @Override + public Serializable loadEntityIdByNaturalId(Map naturalIdParameters, LockOptions lockOptions, + SessionImplementor session) { + return null; + } + + @Override public Comparator getVersionComparator() { return null; } diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java index bcd202a0f0..489c38377b 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/test/ejb3configuration/PersisterClassProviderTest.java @@ -260,12 +260,12 @@ public class PersisterClassProviderTest { public Object[] getNaturalIdentifierSnapshot(Serializable id, SessionImplementor session) { return new Object[0]; } - - @Override - public Serializable loadEntityIdByNaturalId(Map naturalIdParameters, LockOptions lockOptions, - SessionImplementor session) { - return null; - } + + @Override + public Serializable loadEntityIdByNaturalId(Map naturalIdParameters, LockOptions lockOptions, + SessionImplementor session) { + return null; + } @Override public IdentifierGenerator getIdentifierGenerator() {