HHH-16586 When merging a persisted entity with a null Version, Hibernate treats entity as transient instead of throwing an Exception

This commit is contained in:
Andrea Boriero 2023-07-04 17:39:09 +02:00 committed by Andrea Boriero
parent daf8bcc581
commit ebfaf1c707
1 changed files with 22 additions and 12 deletions

View File

@ -39,6 +39,7 @@ import org.hibernate.LazyInitializationException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.MappingException;
import org.hibernate.PropertyValueException;
import org.hibernate.QueryException;
import org.hibernate.Remove;
import org.hibernate.StaleObjectStateException;
@ -3926,20 +3927,29 @@ public abstract class AbstractEntityPersister
// let this take precedence if defined, since it works for
// assigned identifiers
final Object version = getVersion( entity );
final Boolean result = versionMapping.getUnsavedStrategy().isUnsaved( version );
if ( result != null ) {
if ( result && version == null && session.getPersistenceContext().hasLoadContext() ) {
// check if we're currently loading this entity instance, the version
// will be null but the entity cannot be considered transient
final EntityKey entityKey = new EntityKey( id, this );
final LoadingEntityEntry loadingEntityEntry = session.getPersistenceContext()
.getLoadContexts()
.findLoadingEntityEntry( entityKey );
if ( loadingEntityEntry != null && loadingEntityEntry.getEntityInstance() == entity ) {
return false;
final Boolean isUnsaved = versionMapping.getUnsavedStrategy().isUnsaved( version );
if ( isUnsaved != null ) {
if ( isUnsaved ) {
if ( version == null && session.getPersistenceContext().hasLoadContext() ) {
// check if we're currently loading this entity instance, the version
// will be null but the entity cannot be considered transient
final LoadingEntityEntry loadingEntityEntry = session.getPersistenceContext()
.getLoadContexts()
.findLoadingEntityEntry( new EntityKey( id, this ) );
if ( loadingEntityEntry != null && loadingEntityEntry.getEntityInstance() == entity ) {
return false;
}
}
final Boolean unsaved = identifierMapping.getUnsavedStrategy().isUnsaved( id );
if ( unsaved != null && !unsaved ) {
throw new PropertyValueException(
"Detached entity with generated id '" + id + "' has an uninitialized version value '" + version + "'",
getEntityName(),
getVersionColumnName()
);
}
}
return result;
return isUnsaved;
}
}