HHH-2879 - initial clean implementation with no caching
This commit is contained in:
parent
e01ea2ecf8
commit
fb3566b467
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2012, 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 Middleware LLC.
|
||||
* 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
|
||||
|
@ -20,11 +20,9 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate;
|
||||
|
||||
|
||||
/**
|
||||
* Contract for resolving an entity-name from a given entity instance.
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) 2012, 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.
|
||||
|
@ -29,46 +29,40 @@ import java.io.Serializable;
|
|||
* Loads an entity by its primary identifier
|
||||
*
|
||||
* @author Eric Dalquist
|
||||
* @version $Revision$
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface IdentifierLoadAccess<T> {
|
||||
public interface IdentifierLoadAccess {
|
||||
/**
|
||||
* Set the {@link LockOptions} to use when retrieving the entity.
|
||||
* Specify the {@link LockOptions} to use when retrieving the entity.
|
||||
*
|
||||
* @param lockOptions The lock options to use.
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
public IdentifierLoadAccess<T> with(LockOptions lockOptions);
|
||||
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. <br>
|
||||
* <br>
|
||||
* You should not use this method to determine if an instance exists (use <tt>get()</tt> instead). Use this only to
|
||||
* retrieve an instance that you assume exists, where non-existence
|
||||
* would be an actual error. <br>
|
||||
* <br>
|
||||
* 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 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; to check for existence, use {@link #load}
|
||||
* instead. Use this only to retrieve an instance that you assume exists, where non-existence would be an
|
||||
* actual error.
|
||||
*
|
||||
* @param id The identifier for which to obtain a reference
|
||||
*
|
||||
* @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
|
||||
* Return the persistent instance 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, initializing it if needed. This
|
||||
* method never returns an uninitialized instance.
|
||||
*
|
||||
* @param id The identifier
|
||||
*
|
||||
* @return The persistent instance or {@code null}
|
||||
*/
|
||||
public Object load(Serializable id);
|
||||
}
|
||||
|
|
|
@ -39,16 +39,34 @@ public class LockOptions implements Serializable {
|
|||
* NONE represents LockMode.NONE (timeout + scope do not apply)
|
||||
*/
|
||||
public static final LockOptions NONE = new LockOptions(LockMode.NONE);
|
||||
|
||||
/**
|
||||
* READ represents LockMode.READ (timeout + scope do not apply)
|
||||
*/
|
||||
public static final LockOptions READ = new LockOptions(LockMode.READ);
|
||||
|
||||
/**
|
||||
* UPGRADE represents LockMode.UPGRADE (will wait forever for lock and
|
||||
* scope of false meaning only entity is locked)
|
||||
*/
|
||||
public static final LockOptions UPGRADE = new LockOptions(LockMode.UPGRADE);
|
||||
|
||||
/**
|
||||
* Indicates that the database should not wait at all to acquire the pessimistic lock.
|
||||
* @see #getTimeOut
|
||||
*/
|
||||
public static final int NO_WAIT = 0;
|
||||
|
||||
/**
|
||||
* Indicates that there is no timeout for the acquisition.
|
||||
* @see #getTimeOut
|
||||
*/
|
||||
public static final int WAIT_FOREVER = -1;
|
||||
|
||||
private LockMode lockMode = LockMode.NONE;
|
||||
private int timeout = WAIT_FOREVER;
|
||||
private Map aliasSpecificLockModes = null; //initialize lazily as LockOptions is frequently created without needing this
|
||||
|
||||
public LockOptions() {
|
||||
}
|
||||
|
||||
|
@ -56,7 +74,6 @@ public class LockOptions implements Serializable {
|
|||
this.lockMode = lockMode;
|
||||
}
|
||||
|
||||
private LockMode lockMode = LockMode.NONE;
|
||||
|
||||
/**
|
||||
* Retrieve the overall lock mode in effect for this set of options.
|
||||
|
@ -83,7 +100,6 @@ public class LockOptions implements Serializable {
|
|||
return this;
|
||||
}
|
||||
|
||||
private Map aliasSpecificLockModes = null; //initialize lazily as LockOptions is frequently created without needing this
|
||||
|
||||
/**
|
||||
* Specify the {@link LockMode} to be used for a specific query alias.
|
||||
|
@ -167,19 +183,6 @@ public class LockOptions implements Serializable {
|
|||
return aliasSpecificLockModes.entrySet().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the database should not wait at all to acquire the pessimistic lock.
|
||||
* @see #getTimeOut
|
||||
*/
|
||||
public static final int NO_WAIT = 0;
|
||||
/**
|
||||
* Indicates that there is no timeout for the acquisition.
|
||||
* @see #getTimeOut
|
||||
*/
|
||||
public static final int WAIT_FOREVER = -1;
|
||||
|
||||
private int timeout = WAIT_FOREVER;
|
||||
|
||||
/**
|
||||
* Retrieve the current timeout setting.
|
||||
* <p/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) 2012, 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.
|
||||
|
@ -27,37 +27,48 @@ package org.hibernate;
|
|||
* Loads an entity by its natural identifier
|
||||
*
|
||||
* @author Eric Dalquist
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
* @see org.hibernate.annotations.NaturalId
|
||||
*/
|
||||
public interface NaturalIdLoadAccess<T> {
|
||||
public interface NaturalIdLoadAccess {
|
||||
/**
|
||||
* Set the {@link LockOptions} to use when retrieving the entity.
|
||||
* Specify the {@link LockOptions} to use when retrieving the entity.
|
||||
*
|
||||
* @param lockOptions The lock options to use.
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
public NaturalIdLoadAccess<T> with(LockOptions lockOptions);
|
||||
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
|
||||
* @param attributeName The entity attribute name that is marked as a NaturalId
|
||||
* @param value The value of the attribute
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
public NaturalIdLoadAccess<T> using(String attributeName, Object value);
|
||||
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
|
||||
* Return the persistent instance with the natural id value(s) defined by the call(s) to {@link #using}. 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; to check for existence, use {@link #load}
|
||||
* instead. Use this only to retrieve an instance that you assume exists, where non-existence would be an
|
||||
* actual error.
|
||||
*
|
||||
* @return the persistent instance or proxy
|
||||
*/
|
||||
public Object getReference();
|
||||
|
||||
/**
|
||||
* Same behavior as {@link Session#get(Class, java.io.Serializable)}
|
||||
*
|
||||
* @return The entity or null if it does not exist
|
||||
* Return the persistent instance with the natural id value(s) defined by the call(s) to {@link #using}, or
|
||||
* {@code null} if there is no such persistent instance. If the instance is already associated with the session,
|
||||
* return that instance, initializing it if needed. This method never returns an uninitialized instance.
|
||||
*
|
||||
* @return The persistent instance or {@code null}
|
||||
*/
|
||||
public Object load();
|
||||
|
||||
|
|
|
@ -772,48 +772,52 @@ public interface Session extends SharedSessionContract {
|
|||
public String getEntityName(Object object) throws HibernateException;
|
||||
|
||||
/**
|
||||
* Create an {@link IdentifierLoadAccess} instance to retrieve the specified entity by
|
||||
* Create an {@link IdentifierLoadAccess} instance to retrieve the specified entity type 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 entity name of the entity type to be retrieved
|
||||
*
|
||||
* @return load delegate for loading the specified entity type by primary key
|
||||
*
|
||||
* @throws HibernateException If the specified entity name cannot be resolved as an entity name
|
||||
*/
|
||||
public IdentifierLoadAccess<Object> byId(String entityName);
|
||||
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
|
||||
*
|
||||
* @param entityClass The entity type to be retrieved
|
||||
*
|
||||
* @return load delegate for loading the specified entity type by primary key
|
||||
*
|
||||
* @throws HibernateException If the specified Class cannot be resolved as a mapped entity
|
||||
*/
|
||||
public <T> IdentifierLoadAccess<T> byId(Class<T> entityClass);
|
||||
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
|
||||
* @param entityName The entity name of the entity type to be retrieved
|
||||
*
|
||||
* @return load delegate for loading the specified entity type by natural id
|
||||
*
|
||||
* @throws HibernateException If the specified entity name cannot be resolved as an entity name
|
||||
*/
|
||||
public NaturalIdLoadAccess<Object> byNaturalId(String entityName);
|
||||
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
|
||||
* @param entityClass The entity type to be retrieved
|
||||
*
|
||||
* @return load delegate for loading the specified entity type by natural id
|
||||
*
|
||||
* @throws HibernateException If the specified Class cannot be resolved as a mapped entity
|
||||
*/
|
||||
public <T> NaturalIdLoadAccess<T> byNaturalId(Class<T> entityClass);
|
||||
public NaturalIdLoadAccess byNaturalId(Class entityClass);
|
||||
|
||||
/**
|
||||
* Enable the named filter for this current session.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) 2012, 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.
|
||||
|
@ -24,19 +24,15 @@
|
|||
package org.hibernate.event.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
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.tuple.StandardProperty;
|
||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Defines the default load event listeners used by hibernate for loading entities
|
||||
|
@ -44,56 +40,21 @@ import org.jboss.logging.Logger;
|
|||
*
|
||||
* @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 {
|
||||
final SessionImplementor source = event.getSession();
|
||||
|
||||
EntityPersister persister = source.getFactory().getEntityPersister( event.getEntityClassName() );
|
||||
if ( persister == null ) {
|
||||
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.
|
||||
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" );
|
||||
}
|
||||
|
||||
final Map<String, Object> 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 );
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
final Serializable entityId = doResolveNaturalId( event, persister );
|
||||
final Serializable entityId = resolveNaturalId( event );
|
||||
event.setEntityId( entityId );
|
||||
}
|
||||
|
||||
|
@ -103,74 +64,78 @@ public class DefaultResolveNaturalIdEventListener extends AbstractLockUpgradeEve
|
|||
* 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.
|
||||
* @param event The load event
|
||||
*
|
||||
* @return The loaded entity, or null.
|
||||
*/
|
||||
protected Serializable doResolveNaturalId(final ResolveNaturalIdEvent event, final EntityPersister persister) {
|
||||
protected Serializable resolveNaturalId(final ResolveNaturalIdEvent event) {
|
||||
final EntityPersister persister = event.getEntityPersister();
|
||||
|
||||
if ( LOG.isTraceEnabled() )
|
||||
LOG.trace( "Attempting to resolve: "
|
||||
+ MessageHelper.infoString( persister, event.getNaturalId(), event.getSession().getFactory() ) );
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace(
|
||||
"Attempting to resolve: " +
|
||||
MessageHelper.infoString(
|
||||
persister, event.getNaturalIdValues(), event.getSession().getFactory()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Serializable entityId = loadFromSessionCache( event, persister );
|
||||
Serializable entityId = resolveFromSessionCache( event );
|
||||
if ( entityId == REMOVED_ENTITY_MARKER ) {
|
||||
LOG.debugf( "Load request found matching entity in context, but it is scheduled for removal; returning null" );
|
||||
LOG.debug( "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" );
|
||||
LOG.debug(
|
||||
"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() ) );
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace(
|
||||
"Resolved object in session cache: " +
|
||||
MessageHelper.infoString(
|
||||
persister, event.getNaturalIdValues(), event.getSession().getFactory()
|
||||
)
|
||||
);
|
||||
}
|
||||
return entityId;
|
||||
}
|
||||
|
||||
entityId = loadFromSecondLevelCache( event, persister );
|
||||
entityId = loadFromSecondLevelCache( event );
|
||||
if ( entityId != null ) {
|
||||
if ( LOG.isTraceEnabled() )
|
||||
LOG.trace( "Resolved object in second-level cache: "
|
||||
+ MessageHelper.infoString( persister, event.getNaturalId(), event.getSession().getFactory() ) );
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace(
|
||||
"Resolved object in second-level cache: " +
|
||||
MessageHelper.infoString(
|
||||
persister, event.getNaturalIdValues(), event.getSession().getFactory()
|
||||
)
|
||||
);
|
||||
}
|
||||
return entityId;
|
||||
}
|
||||
|
||||
if ( LOG.isTraceEnabled() )
|
||||
LOG.trace( "Object not resolved in any cache: "
|
||||
+ MessageHelper.infoString( persister, event.getNaturalId(), event.getSession().getFactory() ) );
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace(
|
||||
"Object not resolved in any cache: " +
|
||||
MessageHelper.infoString(
|
||||
persister, event.getNaturalIdValues(), event.getSession().getFactory()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return loadFromDatasource( event, persister );
|
||||
return loadFromDatasource( event );
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to locate the entity in the session-level cache.
|
||||
* <p/>
|
||||
* 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.
|
||||
* <p/>
|
||||
* 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.
|
||||
* Attempts to resolve the entity id corresponding to the event's natural id values from the session
|
||||
*
|
||||
* @param event
|
||||
* The load event
|
||||
* @param keyToLoad
|
||||
* The EntityKey representing the entity to be loaded.
|
||||
* @param options
|
||||
* The load options.
|
||||
* @param event The load event
|
||||
*
|
||||
* @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 {
|
||||
protected Serializable resolveFromSessionCache(final ResolveNaturalIdEvent event) {
|
||||
// SessionImplementor session = event.getSession();
|
||||
// Object old = session.getEntityUsingInterceptor( keyToLoad );
|
||||
//
|
||||
|
@ -199,15 +164,11 @@ public class DefaultResolveNaturalIdEventListener extends AbstractLockUpgradeEve
|
|||
/**
|
||||
* 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.
|
||||
* @param event The event
|
||||
*
|
||||
* @return The entity from the second-level cache, or null.
|
||||
*/
|
||||
protected Serializable loadFromSecondLevelCache(final ResolveNaturalIdEvent event, final EntityPersister persister) {
|
||||
protected Serializable loadFromSecondLevelCache(final ResolveNaturalIdEvent event) {
|
||||
|
||||
// final SessionImplementor source = event.getSession();
|
||||
//
|
||||
|
@ -219,7 +180,7 @@ public class DefaultResolveNaturalIdEventListener extends AbstractLockUpgradeEve
|
|||
// final SessionFactoryImplementor factory = source.getFactory();
|
||||
//
|
||||
// final CacheKey ck = source.generateCacheKey(
|
||||
// event.getNaturalId(),
|
||||
// event.getNaturalIdValues(),
|
||||
// persister.getIdentifierType(),
|
||||
// persister.getRootEntityName()
|
||||
// );
|
||||
|
@ -257,19 +218,15 @@ public class DefaultResolveNaturalIdEventListener extends AbstractLockUpgradeEve
|
|||
* 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.
|
||||
* @param event The load event
|
||||
*
|
||||
* @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() );
|
||||
protected Serializable loadFromDatasource(final ResolveNaturalIdEvent event) {
|
||||
return event.getEntityPersister().loadEntityIdByNaturalId(
|
||||
event.getNaturalIdValues(),
|
||||
event.getLockOptions(),
|
||||
event.getSession()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) 2012, 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.
|
||||
|
@ -29,29 +29,39 @@ import java.util.Map;
|
|||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
/**
|
||||
* Defines an event class for the resolving of an entity id from the entity's natural-id
|
||||
*
|
||||
* @author Eric Dalquist
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ResolveNaturalIdEvent extends AbstractEvent {
|
||||
public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE;
|
||||
|
||||
private Map<String, Object> naturalId;
|
||||
private LockOptions lockOptions;
|
||||
private String entityClassName;
|
||||
private final EntityPersister entityPersister;
|
||||
private final Map<String, Object> naturalIdValues;
|
||||
private final LockOptions lockOptions;
|
||||
|
||||
private Serializable entityId;
|
||||
|
||||
public ResolveNaturalIdEvent(Map<String, Object> naturalId, String entityClassName, EventSource source) {
|
||||
this( naturalId, entityClassName, new LockOptions(), source );
|
||||
public ResolveNaturalIdEvent(Map<String, Object> naturalIdValues, EntityPersister entityPersister, EventSource source) {
|
||||
this( naturalIdValues, entityPersister, new LockOptions(), source );
|
||||
}
|
||||
|
||||
public ResolveNaturalIdEvent(Map<String, Object> naturalId, String entityClassName, LockOptions lockOptions,
|
||||
public ResolveNaturalIdEvent(
|
||||
Map<String, Object> naturalIdValues,
|
||||
EntityPersister entityPersister,
|
||||
LockOptions lockOptions,
|
||||
EventSource source) {
|
||||
super( source );
|
||||
|
||||
if ( naturalId == null || naturalId.isEmpty() ) {
|
||||
if ( entityPersister == null ) {
|
||||
throw new IllegalArgumentException( "EntityPersister is required for loading" );
|
||||
}
|
||||
|
||||
if ( naturalIdValues == null || naturalIdValues.isEmpty() ) {
|
||||
throw new IllegalArgumentException( "id to load is required for loading" );
|
||||
}
|
||||
|
||||
|
@ -62,24 +72,25 @@ public class ResolveNaturalIdEvent extends AbstractEvent {
|
|||
lockOptions.setLockMode( DEFAULT_LOCK_MODE );
|
||||
}
|
||||
|
||||
this.naturalId = naturalId;
|
||||
this.entityClassName = entityClassName;
|
||||
this.entityPersister = entityPersister;
|
||||
this.naturalIdValues = naturalIdValues;
|
||||
this.lockOptions = lockOptions;
|
||||
}
|
||||
|
||||
public Map<String, Object> getNaturalId() {
|
||||
return Collections.unmodifiableMap( naturalId );
|
||||
public Map<String, Object> getNaturalIdValues() {
|
||||
return Collections.unmodifiableMap( naturalIdValues );
|
||||
}
|
||||
|
||||
public void setNaturalId(Map<String, Object> naturalId) {
|
||||
this.naturalId = naturalId;
|
||||
public EntityPersister getEntityPersister() {
|
||||
return entityPersister;
|
||||
}
|
||||
|
||||
public String getEntityClassName() {
|
||||
return entityClassName;
|
||||
return getEntityPersister().getEntityName();
|
||||
}
|
||||
|
||||
public void setEntityClassName(String entityClassName) {
|
||||
this.entityClassName = entityClassName;
|
||||
public LockOptions getLockOptions() {
|
||||
return lockOptions;
|
||||
}
|
||||
|
||||
public Serializable getEntityId() {
|
||||
|
@ -89,12 +100,4 @@ public class ResolveNaturalIdEvent extends AbstractEvent {
|
|||
public void setEntityId(Serializable entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
public LockOptions getLockOptions() {
|
||||
return lockOptions;
|
||||
}
|
||||
|
||||
public void setLockOptions(LockOptions lockOptions) {
|
||||
this.lockOptions = lockOptions;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* Copyright (c) 2012, 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.
|
||||
|
@ -31,15 +31,16 @@ import org.hibernate.HibernateException;
|
|||
* Defines the contract for handling of resolve natural id events generated from a session.
|
||||
*
|
||||
* @author Eric Dalquist
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
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 Indicates a problem resolving natural id to primary key
|
||||
*/
|
||||
public void onResolveNaturalId(ResolveNaturalIdEvent event) throws HibernateException;
|
||||
|
||||
|
|
|
@ -366,7 +366,8 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
try {
|
||||
if (ois != null) ois.close();
|
||||
}
|
||||
catch (IOException ex) {}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,7 +386,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
try {
|
||||
oos.close();
|
||||
}
|
||||
catch( IOException ex ) {
|
||||
catch( IOException ignore ) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
@ -413,7 +414,8 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
try {
|
||||
if (ois != null) ois.close();
|
||||
}
|
||||
catch (IOException ex) {}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -495,6 +497,8 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
* if there is not, flush if necessary, make sure the connection has
|
||||
* been committed (if it is not in autocommit mode) and run the after
|
||||
* completion processing
|
||||
*
|
||||
* @param success Was the operation a success
|
||||
*/
|
||||
public void afterOperation(boolean success) {
|
||||
if ( ! transactionCoordinator.isTransactionInProgress() ) {
|
||||
|
@ -891,7 +895,7 @@ 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( new LockOptions( lockMode ) ).getReference( id );
|
||||
}
|
||||
|
||||
public Object load(Class entityClass, Serializable id, LockOptions lockOptions) throws HibernateException {
|
||||
|
@ -899,7 +903,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
|
||||
return this.byId( entityName ).with( lockMode ).getReference( id );
|
||||
return this.byId( entityName ).with( new LockOptions( lockMode ) ).getReference( id );
|
||||
}
|
||||
|
||||
public Object load(String entityName, Serializable id, LockOptions lockOptions) throws HibernateException {
|
||||
|
@ -907,7 +911,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
public Object get(Class entityClass, Serializable id, LockMode lockMode) throws HibernateException {
|
||||
return this.byId( entityClass ).with( lockMode ).load( id );
|
||||
return this.byId( entityClass ).with( new LockOptions( lockMode ) ).load( id );
|
||||
}
|
||||
|
||||
public Object get(Class entityClass, Serializable id, LockOptions lockOptions) throws HibernateException {
|
||||
|
@ -915,7 +919,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
|
||||
return this.byId( entityName ).with( lockMode ).load( id );
|
||||
return this.byId( entityName ).with( new LockOptions( lockMode ) ).load( id );
|
||||
}
|
||||
|
||||
public Object get(String entityName, Serializable id, LockOptions lockOptions) throws HibernateException {
|
||||
|
@ -923,23 +927,23 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
@Override
|
||||
public IdentifierLoadAccessImpl<Object> byId(String entityName) {
|
||||
return new IdentifierLoadAccessImpl<Object>( entityName, Object.class );
|
||||
public IdentifierLoadAccessImpl byId(String entityName) {
|
||||
return new IdentifierLoadAccessImpl( entityName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> IdentifierLoadAccessImpl<T> byId(Class<T> entityClass) {
|
||||
return new IdentifierLoadAccessImpl<T>( entityClass.getName(), entityClass );
|
||||
public IdentifierLoadAccessImpl byId(Class entityClass) {
|
||||
return new IdentifierLoadAccessImpl( entityClass );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NaturalIdLoadAccess<Object> byNaturalId(String entityName) {
|
||||
return new NaturalIdLoadAccessImpl<Object>( entityName, Object.class );
|
||||
public NaturalIdLoadAccess byNaturalId(String entityName) {
|
||||
return new NaturalIdLoadAccessImpl( entityName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> NaturalIdLoadAccess<T> byNaturalId(Class<T> entityClass) {
|
||||
return new NaturalIdLoadAccessImpl<T>( entityClass.getName(), entityClass );
|
||||
public NaturalIdLoadAccess byNaturalId(Class entityClass) {
|
||||
return new NaturalIdLoadAccessImpl( entityClass );
|
||||
}
|
||||
|
||||
private void fireLoad(LoadEvent event, LoadType loadType) {
|
||||
|
@ -2168,47 +2172,45 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
}
|
||||
|
||||
private class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T> {
|
||||
private final String entityName;
|
||||
private final Class<T> entityClass;
|
||||
private class IdentifierLoadAccessImpl implements IdentifierLoadAccess {
|
||||
private final EntityPersister entityPersister;
|
||||
private LockOptions lockOptions;
|
||||
|
||||
private IdentifierLoadAccessImpl(String entityName, Class<T> entityClass) {
|
||||
this.entityName = entityName;
|
||||
this.entityClass = entityClass;
|
||||
private IdentifierLoadAccessImpl(EntityPersister entityPersister) {
|
||||
this.entityPersister = entityPersister;
|
||||
}
|
||||
|
||||
private IdentifierLoadAccessImpl(String entityName) {
|
||||
this( factory.getEntityPersister( entityName ) );
|
||||
if ( entityPersister == null ) {
|
||||
throw new HibernateException( "Unable to locate persister: " + entityName );
|
||||
}
|
||||
}
|
||||
|
||||
private IdentifierLoadAccessImpl(Class entityClass) {
|
||||
this( entityClass.getName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IdentifierLoadAccessImpl<T> with(LockOptions lockOptions) {
|
||||
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<T> with(LockMode lockMode) {
|
||||
this.lockOptions = new LockOptions();
|
||||
this.lockOptions.setLockMode( lockMode );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object getReference(Serializable id) {
|
||||
if ( this.lockOptions != null ) {
|
||||
LoadEvent event = new LoadEvent( id, entityName, lockOptions, SessionImpl.this );
|
||||
LoadEvent event = new LoadEvent( id, entityPersister.getEntityName(), lockOptions, SessionImpl.this );
|
||||
fireLoad( event, LoadEventListener.LOAD );
|
||||
return event.getResult();
|
||||
}
|
||||
|
||||
LoadEvent event = new LoadEvent( id, entityName, false, SessionImpl.this );
|
||||
LoadEvent event = new LoadEvent( id, entityPersister.getEntityName(), false, SessionImpl.this );
|
||||
boolean success = false;
|
||||
try {
|
||||
fireLoad( event, LoadEventListener.LOAD );
|
||||
if ( event.getResult() == null ) {
|
||||
getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id );
|
||||
getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityPersister.getEntityName(), id );
|
||||
}
|
||||
success = true;
|
||||
return event.getResult();
|
||||
|
@ -2221,12 +2223,12 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
@Override
|
||||
public final Object load(Serializable id) {
|
||||
if ( this.lockOptions != null ) {
|
||||
LoadEvent event = new LoadEvent( id, entityName, lockOptions, SessionImpl.this );
|
||||
LoadEvent event = new LoadEvent( id, entityPersister.getEntityName(), lockOptions, SessionImpl.this );
|
||||
fireLoad( event, LoadEventListener.GET );
|
||||
return event.getResult();
|
||||
}
|
||||
|
||||
LoadEvent event = new LoadEvent( id, entityName, false, SessionImpl.this );
|
||||
LoadEvent event = new LoadEvent( id, entityPersister.getEntityName(), false, SessionImpl.this );
|
||||
boolean success = false;
|
||||
try {
|
||||
fireLoad( event, LoadEventListener.GET );
|
||||
|
@ -2239,39 +2241,47 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
}
|
||||
|
||||
private class NaturalIdLoadAccessImpl<T> implements NaturalIdLoadAccess<T> {
|
||||
private final String entityName;
|
||||
private final Class<T> entityClass;
|
||||
private class NaturalIdLoadAccessImpl implements NaturalIdLoadAccess {
|
||||
private final EntityPersister entityPersister;
|
||||
private final Map<String, Object> naturalIdParameters = new LinkedHashMap<String, Object>();
|
||||
private LockOptions lockOptions;
|
||||
|
||||
private NaturalIdLoadAccessImpl(String entityName, Class<T> entityClass) {
|
||||
this.entityName = entityName;
|
||||
this.entityClass = entityClass;
|
||||
private NaturalIdLoadAccessImpl(EntityPersister entityPersister) {
|
||||
this.entityPersister = entityPersister;
|
||||
}
|
||||
|
||||
private NaturalIdLoadAccessImpl(String entityName) {
|
||||
this( factory.getEntityPersister( entityName ) );
|
||||
if ( entityPersister == null ) {
|
||||
throw new HibernateException( "Unable to locate persister: " + entityName );
|
||||
}
|
||||
}
|
||||
|
||||
private NaturalIdLoadAccessImpl(Class entityClass) {
|
||||
this( entityClass.getName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public final NaturalIdLoadAccess<T> with(LockOptions lockOptions) {
|
||||
public final NaturalIdLoadAccess with(LockOptions lockOptions) {
|
||||
this.lockOptions = lockOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NaturalIdLoadAccess<T> using(String attributeName, Object value) {
|
||||
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 );
|
||||
final ResolveNaturalIdEvent event =
|
||||
new ResolveNaturalIdEvent( naturalIdParameters, entityPersister, SessionImpl.this );
|
||||
fireResolveNaturalId( event );
|
||||
return event.getEntityId();
|
||||
}
|
||||
|
||||
protected IdentifierLoadAccess<T> getIdentifierLoadAccess() {
|
||||
final IdentifierLoadAccessImpl<T> identifierLoadAccess = new SessionImpl.IdentifierLoadAccessImpl<T>(
|
||||
entityName, entityClass );
|
||||
protected IdentifierLoadAccess getIdentifierLoadAccess() {
|
||||
final IdentifierLoadAccessImpl identifierLoadAccess = new IdentifierLoadAccessImpl( entityPersister );
|
||||
if ( this.lockOptions != null ) {
|
||||
identifierLoadAccess.with( lockOptions );
|
||||
}
|
||||
|
|
|
@ -4504,29 +4504,59 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
@Override
|
||||
public Serializable loadEntityIdByNaturalId(Map<String, ?> naturalIdParameters, LockOptions lockOptions,
|
||||
public Serializable loadEntityIdByNaturalId(
|
||||
Map<String, ?> naturalIdValues,
|
||||
LockOptions lockOptions,
|
||||
SessionImplementor session) {
|
||||
if ( !hasNaturalIdentifier() ) {
|
||||
throw new MappingException( "persistent class did not define a natural-id : "
|
||||
+ MessageHelper.infoString( this ) );
|
||||
|
||||
if ( ! entityMetamodel.hasNaturalIdentifier() ) {
|
||||
throw new HibernateException(
|
||||
String.format( "Entity [%s] does not define a natural-id", getEntityName() )
|
||||
);
|
||||
}
|
||||
|
||||
final int[] naturalIdPropertyIndexes = this.getNaturalIdentifierProperties();
|
||||
if ( naturalIdPropertyIndexes.length != naturalIdValues.size() ) {
|
||||
throw new HibernateException(
|
||||
String.format(
|
||||
"Entity [%s] defines its natural-id with %d properties but only %d were specified",
|
||||
getEntityName(),
|
||||
naturalIdPropertyIndexes.length,
|
||||
naturalIdValues.size()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracef(
|
||||
"Resolving natural-id [%s] to id : %s ",
|
||||
naturalIdValues,
|
||||
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()
|
||||
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];
|
||||
for ( int naturalIdIdx : naturalIdPropertyIndexes ) {
|
||||
final StandardProperty property = entityMetamodel.getProperties()[naturalIdIdx];
|
||||
if ( ! naturalIdValues.containsKey( property.getName() ) ) {
|
||||
throw new HibernateException(
|
||||
String.format(
|
||||
"No value specified for natural-id property %s#%s",
|
||||
getEntityName(),
|
||||
property.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
final Object value = naturalIdValues.get( property.getName() );
|
||||
if ( value == null ) {
|
||||
|
||||
final StandardProperty[] properties = entityMetamodel.getProperties();
|
||||
final StandardProperty property = properties[naturalIdIdx];
|
||||
|
||||
final Object value = naturalIdParameters.get( property.getName() );
|
||||
}
|
||||
|
||||
final Type propertyType = property.getType();
|
||||
propertyType.nullSafeSet( ps, value, positions, session );
|
||||
|
@ -4553,9 +4583,13 @@ public abstract class AbstractEntityPersister
|
|||
catch ( SQLException e ) {
|
||||
throw getFactory().getSQLExceptionHelper().convert(
|
||||
e,
|
||||
"could not retrieve entity id: "
|
||||
+ MessageHelper.infoString( this, naturalIdParameters, getFactory() ),
|
||||
sqlEntityIdByNaturalIdString );
|
||||
String.format(
|
||||
"could not resolve natural-id [%s] to id : %s",
|
||||
naturalIdValues,
|
||||
MessageHelper.infoString( this )
|
||||
),
|
||||
sqlEntityIdByNaturalIdString
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4580,17 +4614,15 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
final int naturalIdIdx = naturalIdPropertyIndexes[propIdx];
|
||||
final String tableAlias = generateTableAlias( rootAlias, propertyTableNumbers[naturalIdIdx] );
|
||||
|
||||
final String[] propertyColumnNames = getPropertyColumnNames( naturalIdIdx );
|
||||
final String[] aliasedPropertyColumns = StringHelper.qualify( rootAlias, propertyColumnNames );
|
||||
final String[] aliasedPropertyColumns = StringHelper.qualify( tableAlias, propertyColumnNames );
|
||||
|
||||
whereClause.append( StringHelper.join( "=? and ", aliasedPropertyColumns ) ).append( "=?" );
|
||||
}
|
||||
|
||||
whereClause.append( whereJoinFragment( getRootAlias(), true, false ) );
|
||||
|
||||
String sql = select.setOuterJoins( "", "" ).setWhereClause( whereClause.toString() ).toStatementString();
|
||||
return sql;
|
||||
return select.setOuterJoins( "", "" ).setWhereClause( whereClause.toString() ).toStatementString();
|
||||
}
|
||||
|
||||
protected String concretePropertySelectFragmentSansLeadingComma(String alias, boolean[] include) {
|
||||
|
|
Loading…
Reference in New Issue