HHH-18524 Fix binding of meta-annotated id generators for id-class
This commit is contained in:
parent
6d0c9599e6
commit
b8b8f011dc
|
@ -66,11 +66,8 @@ import static org.hibernate.boot.model.internal.BinderHelper.getPath;
|
|||
import static org.hibernate.boot.model.internal.BinderHelper.getPropertyOverriddenByMapperOrMapsId;
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.getRelativePath;
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.hasToOneAnnotation;
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.isGlobalGeneratorNameGlobal;
|
||||
import static org.hibernate.boot.model.internal.DialectOverridesAnnotationHelper.getOverridableAnnotation;
|
||||
import static org.hibernate.boot.model.internal.GeneratorBinder.buildGenerators;
|
||||
import static org.hibernate.boot.model.internal.GeneratorBinder.makeIdGenerator;
|
||||
import static org.hibernate.boot.model.internal.GeneratorStrategies.generatorStrategy;
|
||||
import static org.hibernate.boot.model.internal.GeneratorBinder.createIdGeneratorsFromGeneratorAnnotations;
|
||||
import static org.hibernate.boot.model.internal.PropertyBinder.addElementsOfClass;
|
||||
import static org.hibernate.boot.model.internal.PropertyBinder.processElementAnnotations;
|
||||
import static org.hibernate.boot.model.internal.PropertyHolderBuilder.buildPropertyHolder;
|
||||
|
@ -464,7 +461,7 @@ public class EmbeddableBinder {
|
|||
? Nullability.FORCED_NULL
|
||||
: ( isNullable ? Nullability.NO_CONSTRAINT : Nullability.FORCED_NOT_NULL ),
|
||||
propertyAnnotatedElement,
|
||||
new HashMap<>(),
|
||||
Map.of(),
|
||||
entityBinder,
|
||||
isIdentifierMapper,
|
||||
isComponentEmbedded,
|
||||
|
@ -473,18 +470,27 @@ public class EmbeddableBinder {
|
|||
inheritanceStatePerClass
|
||||
);
|
||||
|
||||
final MemberDetails property = propertyAnnotatedElement.getAttributeMember();
|
||||
if ( property.hasDirectAnnotationUsage( GeneratedValue.class ) ) {
|
||||
if ( isIdClass || subholder.isOrWithinEmbeddedId() ) {
|
||||
processGeneratedId( context, component, property );
|
||||
}
|
||||
else {
|
||||
throw new AnnotationException(
|
||||
"Property '" + property.getName() + "' of '"
|
||||
+ getPath( propertyHolder, inferredData )
|
||||
+ "' is annotated '@GeneratedValue' but is not part of an identifier" );
|
||||
final MemberDetails member = propertyAnnotatedElement.getAttributeMember();
|
||||
if ( isIdClass || subholder.isOrWithinEmbeddedId() ) {
|
||||
final Property property = findProperty( component, member.getName() );
|
||||
if ( property != null ) {
|
||||
// Identifier properties are always simple values
|
||||
final SimpleValue value = (SimpleValue) property.getValue();
|
||||
createIdGeneratorsFromGeneratorAnnotations(
|
||||
subholder,
|
||||
propertyAnnotatedElement,
|
||||
value,
|
||||
Map.of(),
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
else if ( member.hasDirectAnnotationUsage( GeneratedValue.class ) ) {
|
||||
throw new AnnotationException(
|
||||
"Property '" + member.getName() + "' of '"
|
||||
+ getPath( propertyHolder, inferredData )
|
||||
+ "' is annotated '@GeneratedValue' but is not part of an identifier" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( compositeUserType != null ) {
|
||||
|
@ -494,6 +500,15 @@ public class EmbeddableBinder {
|
|||
return component;
|
||||
}
|
||||
|
||||
private static Property findProperty(Component component, String name) {
|
||||
for ( Property property : component.getProperties() ) {
|
||||
if ( property.getName().equals( name ) ) {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static CompositeUserType<?> compositeUserType(
|
||||
Class<? extends CompositeUserType<?>> compositeUserTypeClass,
|
||||
MetadataBuildingContext context) {
|
||||
|
@ -812,40 +827,6 @@ public class EmbeddableBinder {
|
|||
|| property.hasDirectAnnotationUsage(ManyToMany.class);
|
||||
}
|
||||
|
||||
private static void processGeneratedId(MetadataBuildingContext context, Component component, MemberDetails property) {
|
||||
final GeneratedValue generatedValue = property.getDirectAnnotationUsage( GeneratedValue.class );
|
||||
final String generatorType =
|
||||
generatorStrategy( generatedValue.strategy(), generatedValue.generator(), property.getType() );
|
||||
final String generator = generatedValue.generator();
|
||||
|
||||
final SimpleValue value = (SimpleValue) component.getProperty( property.getName()).getValue();
|
||||
if ( isGlobalGeneratorNameGlobal( context ) ) {
|
||||
buildGenerators( property, context );
|
||||
context.getMetadataCollector().addSecondPass( new IdGeneratorResolverSecondPass(
|
||||
value,
|
||||
property,
|
||||
generatorType,
|
||||
generator,
|
||||
context
|
||||
) );
|
||||
|
||||
// handleTypeDescriptorRegistrations( property, context );
|
||||
// bindEmbeddableInstantiatorRegistrations( property, context );
|
||||
// bindCompositeUserTypeRegistrations( property, context );
|
||||
// handleConverterRegistrations( property, context );
|
||||
}
|
||||
else {
|
||||
makeIdGenerator(
|
||||
value,
|
||||
property,
|
||||
generatorType,
|
||||
generator,
|
||||
context,
|
||||
new HashMap<>( buildGenerators( property, context ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processIdClassElements(
|
||||
PropertyHolder propertyHolder,
|
||||
PropertyData baseInferredData,
|
||||
|
|
|
@ -65,6 +65,7 @@ import static org.hibernate.boot.model.internal.GeneratorParameters.interpretSeq
|
|||
import static org.hibernate.boot.model.internal.GeneratorParameters.interpretTableGenerator;
|
||||
import static org.hibernate.boot.model.internal.GeneratorStrategies.generatorClass;
|
||||
import static org.hibernate.boot.model.internal.GeneratorStrategies.generatorStrategy;
|
||||
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
|
||||
import static org.hibernate.internal.util.StringHelper.qualify;
|
||||
import static org.hibernate.resource.beans.internal.Helper.allowExtensionsInCdi;
|
||||
|
||||
|
@ -600,7 +601,7 @@ public class GeneratorBinder {
|
|||
MemberDetails idMember) {
|
||||
//manage composite related metadata
|
||||
//guess if its a component and find id data access (property, field etc)
|
||||
final GeneratedValue generatedValue = idMember.getDirectAnnotationUsage( GeneratedValue.class );
|
||||
final GeneratedValue generatedValue = castNonNull( idMember.getDirectAnnotationUsage( GeneratedValue.class ) );
|
||||
final String generatorType =
|
||||
generatorStrategy( generatedValue.strategy(), generatedValue.generator(), idMember.getType() );
|
||||
final String generatorName = generatedValue.generator();
|
||||
|
|
|
@ -1135,11 +1135,11 @@ public class PropertyBinder {
|
|||
);
|
||||
}
|
||||
else if ( propertyBinder.isId() ) {
|
||||
//components and regular basic types create SimpleValue objects
|
||||
if ( isIdentifierMapper ) {
|
||||
throw new AnnotationException( "Property '"+ getPath( propertyHolder, inferredData )
|
||||
+ "' belongs to an '@IdClass' and may not be annotated '@Id' or '@EmbeddedId'" );
|
||||
}
|
||||
//components and regular basic types create SimpleValue objects
|
||||
createIdGeneratorsFromGeneratorAnnotations(
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
|
|
|
@ -3,12 +3,13 @@ package org.hibernate.orm.test.tenantidpk;
|
|||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.IdClass;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import org.hibernate.annotations.TenantId;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Entity @IdClass(TenantizedId.class)
|
||||
public class Account {
|
||||
|
||||
@Id @GeneratedValue Long id;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.test.tenantidpk;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.Embeddable;
|
||||
|
||||
@Embeddable
|
||||
public class TenantizedId {
|
||||
Long id;
|
||||
UUID tenantId;
|
||||
|
||||
public TenantizedId(Long id, UUID tenantId) {
|
||||
this.id = id;
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
TenantizedId() {}
|
||||
}
|
Loading…
Reference in New Issue