diff --git a/hibernate-core/src/main/java/org/hibernate/Session.java b/hibernate-core/src/main/java/org/hibernate/Session.java index 3e89651556..3bbbf79041 100644 --- a/hibernate-core/src/main/java/org/hibernate/Session.java +++ b/hibernate-core/src/main/java/org/hibernate/Session.java @@ -780,6 +780,18 @@ public interface Session extends SharedSessionContract, EntityManager { * @return the entity name */ String getEntityName(Object object); + + /** + * Return the persistent instance with the same identity as the given instance, which + * might be detached, assuming that the instance is still persistent in the database. + * This method never results in access to the underlying data store, and thus might + * return a proxy that must be initialized explicitly. + * + * @param object a detached persistent instance + * + * @return the persistent instance or proxy + */ + T getReference(T object); /** * Create an {@link IdentifierLoadAccess} instance to retrieve the specified entity type by diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java index d6cf5456b6..d881329649 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java @@ -900,6 +900,11 @@ public String getEntityName(Object object) { return delegate.getEntityName( object ); } + @Override + public T getReference(T object) { + return delegate.getReference( object ); + } + @Override public IdentifierLoadAccess byId(String entityName) { return delegate.byId( entityName ); 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 e3d4d3a720..1f47208f5e 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -1703,6 +1703,19 @@ public String getEntityName(Object object) { return entry.getPersister().getEntityName(); } + @Override @SuppressWarnings("unchecked") + public T getReference(T object) { + checkOpen(); + if ( object instanceof HibernateProxy ) { + LazyInitializer initializer = ( (HibernateProxy) object ).getHibernateLazyInitializer(); + return (T) getReference( initializer.getPersistentClass(), initializer.getIdentifier() ); + } + else { + EntityPersister persister = getEntityPersister( null, object ); + return (T) getReference( persister.getMappedClass(), persister.getIdentifier(object, this) ); + } + } + private void throwTransientObjectException(Object object) throws HibernateException { throw new TransientObjectException( "object references an unsaved transient instance - save the transient instance before flushing: " +