Skip to content

[7.0] Various backports #10469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion ci/build.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#! /bin/bash

goal=
if [ "$RDBMS" == "h2" ]; then
if [ "$RDBMS" == "h2" ] || [ "$RDBMS" == "" ]; then
# This is the default.
goal="preVerifyRelease"
# Settings needed for `preVerifyRelease` execution - for asciidoctor doc rendering
Expand Down Expand Up @@ -77,6 +77,9 @@ elif [ "$RDBMS" == "altibase" ]; then
goal="-Pdb=altibase"
elif [ "$RDBMS" == "informix" ]; then
goal="-Pdb=informix"
else
echo "Invalid value for RDBMS: $RDBMS"
exit 1
fi

function logAndExec() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,11 @@ private String jsonCustomWriteExpression(String customWriteExpression, JdbcMappi
if ( uuidFunctions ) {
return "bin_to_uuid(" + customWriteExpression + ")";
}
else if ( jsonType ) {
return "insert(insert(insert(insert(lower(hex(" + customWriteExpression + ")),21,0,'-'),17,0,'-'),13,0,'-'),9,0,'-')";
}
else {
return "regexp_replace(lower(hex(" + customWriteExpression + ")),'^(.{8})(.{4})(.{4})(.{4})(.{12})$','$1-$2-$3-$4-$5')";
return "regexp_replace(lower(hex(" + customWriteExpression + ")),'^(.{8})(.{4})(.{4})(.{4})(.{12})$','\\\\1-\\\\2-\\\\3-\\\\4-\\\\5')";
}
}
// Fall-through intended
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,8 @@ public void visitOffsetFetchClause(QueryPart queryPart) {
protected void renderComparison(Expression lhs, ComparisonOperator operator, Expression rhs) {
final JdbcMappingContainer lhsExpressionType = lhs.getExpressionType();
if ( lhsExpressionType != null && lhsExpressionType.getJdbcTypeCount() == 1
&& lhsExpressionType.getSingleJdbcMapping().getJdbcType().isJson() ) {
&& lhsExpressionType.getSingleJdbcMapping().getJdbcType().isJson()
&& getDialect().getVersion().isSameOrAfter( 10, 7 ) ) {
switch ( operator ) {
case DISTINCT_FROM:
appendSql( "case when json_equals(" );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import org.hibernate.property.access.internal.PropertyAccessMapImpl;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.query.sqm.tree.domain.SqmDomainType;
import org.hibernate.query.sqm.tree.domain.SqmMappedSuperclassDomainType;
import org.hibernate.type.AnyType;
import org.hibernate.type.BasicType;
import org.hibernate.type.CollectionType;
Expand Down Expand Up @@ -740,56 +741,70 @@ private static Member resolveMappedSuperclassMember(
Property property,
MappedSuperclassDomainType<?> ownerType,
MetadataContext context) {
final EntityPersister declaringEntity =
getDeclaringEntity( (AbstractIdentifiableType<?>) ownerType, context );
if ( declaringEntity != null ) {
return resolveEntityMember( property, declaringEntity );
}
else {
final ManagedDomainType<?> subType = ownerType.getSubTypes().iterator().next();
final Type.PersistenceType persistenceType = subType.getPersistenceType();
return switch ( persistenceType ) {
case ENTITY ->
resolveEntityMember( property,
getDeclaringEntity( (AbstractIdentifiableType<?>) subType, context ) );
case MAPPED_SUPERCLASS ->
resolveMappedSuperclassMember( property, (MappedSuperclassDomainType<?>) subType, context );
case EMBEDDABLE ->
resolveEmbeddedMember( property, (EmbeddableDomainType<?>) subType, context );
default -> throw new IllegalArgumentException( "Unexpected PersistenceType: " + persistenceType );
};
}
return property.getGetter( ownerType.getJavaType() ).getMember();
// final EntityPersister declaringEntity =
// getDeclaringEntity( (AbstractIdentifiableType<?>) ownerType, context );
// if ( declaringEntity != null ) {
// return resolveEntityMember( property, declaringEntity );
// }
// else {
// final ManagedDomainType<?> subType = ownerType.getSubTypes().iterator().next();
// final Type.PersistenceType persistenceType = subType.getPersistenceType();
// return switch ( persistenceType ) {
// case ENTITY ->
// resolveEntityMember( property,
// getDeclaringEntity( (AbstractIdentifiableType<?>) subType, context ) );
// case MAPPED_SUPERCLASS ->
// resolveMappedSuperclassMember( property, (MappedSuperclassDomainType<?>) subType, context );
// case EMBEDDABLE ->
// resolveEmbeddedMember( property, (EmbeddableDomainType<?>) subType, context );
// default -> throw new IllegalArgumentException( "Unexpected PersistenceType: " + persistenceType );
// };
// }
}

private final MemberResolver identifierMemberResolver = (attributeContext, metadataContext) -> {
final AbstractIdentifiableType<?> identifiableType =
(AbstractIdentifiableType<?>) attributeContext.getOwnerType();
final EntityPersister declaringEntityMapping = getDeclaringEntity( identifiableType, metadataContext );
final EntityIdentifierMapping identifierMapping = declaringEntityMapping.getIdentifierMapping();
final Property propertyMapping = attributeContext.getPropertyMapping();
return !propertyMapping.getName().equals( identifierMapping.getAttributeName() )
// this *should* indicate processing part of an IdClass...
? virtualIdentifierMemberResolver.resolveMember( attributeContext, metadataContext )
: getter( declaringEntityMapping, propertyMapping,
identifierMapping.getAttributeName(), identifierMapping.getJavaType().getJavaTypeClass() );

if ( identifiableType instanceof SqmMappedSuperclassDomainType<?> ) {
return attributeContext.getPropertyMapping()
.getGetter( identifiableType.getJavaType() )
.getMember();
}
else {
final EntityPersister declaringEntityMapping = getDeclaringEntity( identifiableType, metadataContext );
final EntityIdentifierMapping identifierMapping = declaringEntityMapping.getIdentifierMapping();
final Property propertyMapping = attributeContext.getPropertyMapping();
return !propertyMapping.getName().equals( identifierMapping.getAttributeName() )
// this *should* indicate processing part of an IdClass...
? virtualIdentifierMemberResolver.resolveMember( attributeContext, metadataContext )
: getter( declaringEntityMapping, propertyMapping,
identifierMapping.getAttributeName(), identifierMapping.getJavaType().getJavaTypeClass() );
}
};

private final MemberResolver versionMemberResolver = (attributeContext, metadataContext) -> {
final AbstractIdentifiableType<?> identifiableType =
(AbstractIdentifiableType<?>) attributeContext.getOwnerType();
final EntityPersister entityPersister = getDeclaringEntity( identifiableType, metadataContext );
final EntityVersionMapping versionMapping = entityPersister.getVersionMapping();
assert entityPersister.isVersioned();
assert versionMapping != null;

final String versionPropertyName = attributeContext.getPropertyMapping().getName();
if ( !versionPropertyName.equals( versionMapping.getVersionAttribute().getAttributeName() ) ) {
// this should never happen, but to be safe...
throw new IllegalArgumentException( "Given property did not match declared version property" );
}
return getter( entityPersister, attributeContext.getPropertyMapping(),
versionPropertyName, versionMapping.getJavaType().getJavaTypeClass() );
if ( identifiableType instanceof SqmMappedSuperclassDomainType<?> ) {
return attributeContext.getPropertyMapping()
.getGetter( identifiableType.getJavaType() )
.getMember();
}
else {
final EntityPersister entityPersister = getDeclaringEntity( identifiableType, metadataContext );
final EntityVersionMapping versionMapping = entityPersister.getVersionMapping();
assert entityPersister.isVersioned();
assert versionMapping != null;

final String versionPropertyName = attributeContext.getPropertyMapping().getName();
if ( !versionPropertyName.equals( versionMapping.getVersionAttribute().getAttributeName() ) ) {
// this should never happen, but to be safe...
throw new IllegalArgumentException( "Given property did not match declared version property" );
}
return getter( entityPersister, attributeContext.getPropertyMapping(),
versionPropertyName, versionMapping.getJavaType().getJavaTypeClass() );
}
};

private static Member getter(EntityPersister persister, Property property, String name, Class<?> type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@ private void handleConflictClause(
final List<ColumnReference> assignmentColumns = new ArrayList<>( assignments.size() );
final QuerySpec updateSubquery = new QuerySpec( false, 1 );
for ( Assignment assignment : assignments ) {
assignmentColumns.add( (ColumnReference) assignment.getAssignable() );
assignmentColumns.addAll( assignment.getAssignable().getColumnReferences() );
updateSubquery.getSelectClause().addSqlSelection(
new SqlSelectionImpl( assignment.getAssignedValue() )
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.mapping.identifier.composite;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Version;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertNotNull;

/**
* This test Fails
*/
@DomainModel(
annotatedClasses = {
CompositeInheritanceFailTest.TupAbstractEntity.class,
CompositeInheritanceFailTest.DummyEntity.class,
CompositeInheritanceFailTest.TestEntity.class, // Here the class is called TestEntity
CompositeInheritanceFailTest.Test2Entity.class,
}
)
@ServiceRegistry(
settings = {
// For your own convenience to see generated queries:
@Setting(name = AvailableSettings.SHOW_SQL, value = "true"),
@Setting(name = AvailableSettings.FORMAT_SQL, value = "true"),
// @Setting( name = AvailableSettings.GENERATE_STATISTICS, value = "true" ),
}
)
@SessionFactory
@Jira("HHH-19076")
public class CompositeInheritanceFailTest {

@Test
void hhh19076FailingTest(SessionFactoryScope scope) {
scope.inTransaction( em -> {
TestEntity e1 = new TestEntity("foo", "bar");
em.persist(e1);

CompositeIdClass key = e1.getCompositeId();
TestEntity e2 = em.find(TestEntity.class, key);
assertNotNull(e2);
} );
}

@Test
void hhh19076FailingTest2(SessionFactoryScope scope) {
scope.inTransaction( em -> {
Test2Entity e1 = new Test2Entity("foo", "xxxxxx");
em.persist(e1);

CompositeId2Class key = e1.getCompositeId();
Test2Entity e2 = em.find(Test2Entity.class, key);
assertNotNull(e2);
} );
}

@MappedSuperclass
public static abstract class TupAbstractEntity {
@Id
private String oid = null;


@SuppressWarnings("this-escape")
protected TupAbstractEntity() {
}

protected TupAbstractEntity(String oid) {
this.oid = oid;
}

public String getOid() {
return oid;
}

}

@Entity
public static class DummyEntity extends TupAbstractEntity {
}

@Entity
@IdClass(CompositeIdClass.class)
public static class TestEntity extends TupAbstractEntity {

@Id
private String myId;

protected TestEntity() {
// for JPA
}

public TestEntity(String oid, String myId) {
super(oid);
this.myId = myId;
}

public String myId() {
return myId;
}

public CompositeIdClass getCompositeId() {
return new CompositeIdClass(getOid(), myId);
}

}

@Entity
@IdClass(CompositeId2Class.class)
public static class Test2Entity extends TupAbstractEntity {

@Id
private String otherId;

@Version
private long tanum = 0;

protected Test2Entity() {
// for JPA
}

public Test2Entity(String oid, String otherId) {
super(oid);
this.otherId = otherId;
}

public String myId() {
return otherId;
}

public long tanum() {
return tanum;
}

public CompositeId2Class getCompositeId() {
return new CompositeId2Class(getOid(), otherId);
}

}

public static class CompositeIdClass {

private String oid;
private String myId;

public CompositeIdClass(String oid, String myId) {
this.oid = oid;
this.myId = myId;
}

public CompositeIdClass() {
}

public String oid() {
return oid;
}

public String myId() {
return myId;
}

}

public static class CompositeId2Class {

private String oid;
private String otherId;

public CompositeId2Class(String oid, String otherId) {
this.oid = oid;
this.otherId = otherId;
}

public CompositeId2Class() {
}

public String oid() {
return oid;
}

public String otherId() {
return otherId;
}

}

}
Loading