From 80b12c46e74cf6abc0f7bdcc9c075598e49c31a5 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 28 Aug 2024 19:12:50 -0500 Subject: [PATCH] HHH-18535 - Support jakarta.persistence.EntityResult#lockMode --- .../boot/query/SqlResultSetMappingDescriptor.java | 7 ++++++- .../complete/CompleteResultBuilderEntityJpa.java | 10 +++++++--- .../test/query/resultmapping/EntityResultTests.java | 8 ++++++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDescriptor.java b/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDescriptor.java index 4fe3ba42fe..a06d01c7c2 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDescriptor.java @@ -46,6 +46,7 @@ import jakarta.persistence.ColumnResult; import jakarta.persistence.ConstructorResult; import jakarta.persistence.EntityResult; import jakarta.persistence.FieldResult; +import jakarta.persistence.LockModeType; import jakarta.persistence.SqlResultSetMapping; import static org.hibernate.internal.util.collections.CollectionHelper.arrayList; @@ -231,6 +232,7 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr private final NavigablePath navigablePath; private final String entityName; private final String discriminatorColumn; + private final LockModeType lockMode; private final Map explicitFetchMappings; @@ -239,6 +241,7 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr this.navigablePath = new NavigablePath( entityName ); this.discriminatorColumn = entityResult.discriminatorColumn(); + this.lockMode = entityResult.lockMode(); this.explicitFetchMappings = extractFetchMappings( navigablePath, entityResult ); } @@ -288,7 +291,9 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr return new ResultMementoEntityJpa( entityDescriptor, - LockMode.READ, + lockMode == LockModeType.OPTIMISTIC + ? LockMode.NONE + : LockMode.fromJpaLockMode( lockMode ), discriminatorMemento, fetchMementos ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderEntityJpa.java b/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderEntityJpa.java index 8b7e317047..23f5ece320 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderEntityJpa.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderEntityJpa.java @@ -21,6 +21,7 @@ import org.hibernate.query.results.ResultBuilder; import org.hibernate.query.results.ResultsHelper; import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy; import org.hibernate.spi.NavigablePath; +import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.entity.EntityResult; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; @@ -90,6 +91,9 @@ public class CompleteResultBuilderEntityJpa implements CompleteResultBuilderEnti int resultPosition, BiFunction legacyFetchResolver, DomainResultCreationState domainResultCreationState) { + final String implicitAlias = entityDescriptor.getSqlAliasStem() + resultPosition; + final SqlAliasBase sqlAliasBase = domainResultCreationState.getSqlAliasBaseManager().createSqlAliasBase( implicitAlias ); + final DomainResultCreationStateImpl impl = ResultsHelper.impl( domainResultCreationState ); impl.disallowPositionalSelections(); @@ -103,8 +107,8 @@ public class CompleteResultBuilderEntityJpa implements CompleteResultBuilderEnti // since this is only used for result set mappings, the canUseInnerJoins value is irrelevant. true, navigablePath, - null, - null, + implicitAlias, + sqlAliasBase, null, impl.getSqlAstCreationState() ) @@ -113,7 +117,7 @@ public class CompleteResultBuilderEntityJpa implements CompleteResultBuilderEnti return new EntityResultImpl( navigablePath, entityDescriptor, - null, + implicitAlias, lockMode, (entityResult) -> { if ( discriminatorFetchBuilder == null ) { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/resultmapping/EntityResultTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/resultmapping/EntityResultTests.java index 1c4b79d5dd..ce563372c6 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/resultmapping/EntityResultTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/resultmapping/EntityResultTests.java @@ -19,12 +19,14 @@ import java.util.Set; import jakarta.persistence.LockModeType; import org.hibernate.cfg.AvailableSettings; +import org.hibernate.dialect.H2Dialect; import org.hibernate.query.named.NamedResultSetMappingMemento; import org.hibernate.testing.orm.domain.gambit.EntityOfBasics; import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.FailureExpected; import org.hibernate.testing.orm.junit.Jira; +import org.hibernate.testing.orm.junit.RequiresDialect; import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.hibernate.testing.orm.junit.Setting; @@ -123,8 +125,10 @@ public class EntityResultTests extends AbstractUsageTest { } @Test - @FailureExpected( jiraKey = "HHH-18535", reason = "Support for @EntityResult(lockMode) not implemented yet") - @Jira( "https://hibernate.atlassian.net/browse/HHH-18535" ) + @RequiresDialect( + value = H2Dialect.class, + comment = "We don't really care about the execution on the database, just how the result-set is handled. Some databases (mssql) don't like this query" + ) public void testImplicitAttributeMappingWithLockMode(SessionFactoryScope scope) { scope.inTransaction( session -> {