diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EmbeddableBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EmbeddableBinder.java index 8781b94be9..674adad8f6 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EmbeddableBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EmbeddableBinder.java @@ -388,7 +388,15 @@ public class EmbeddableBinder { final XProperty property = propertyAnnotatedElement.getProperty(); if ( property.isAnnotationPresent( GeneratedValue.class ) ) { - processGeneratedId( context, component, property ); + 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" ); + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java index 527a30c39c..d6e913d48c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java @@ -67,6 +67,7 @@ import org.hibernate.annotations.Where; import org.hibernate.annotations.common.reflection.ReflectionManager; import org.hibernate.annotations.common.reflection.XAnnotatedElement; import org.hibernate.annotations.common.reflection.XClass; +import org.hibernate.annotations.common.reflection.XProperty; import org.hibernate.binder.TypeBinder; import org.hibernate.boot.model.IdentifierGeneratorDefinition; import org.hibernate.boot.model.NamedEntityGraphDefinition; @@ -116,6 +117,7 @@ import jakarta.persistence.ConstraintMode; import jakarta.persistence.DiscriminatorColumn; import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; import jakarta.persistence.IdClass; import jakarta.persistence.Inheritance; import jakarta.persistence.InheritanceType; @@ -1015,14 +1017,22 @@ public class EntityBinder { for ( PropertyData propertyAnnotatedElement : elementsToProcess.getElements() ) { final String propertyName = propertyAnnotatedElement.getPropertyName(); if ( !idPropertiesIfIdClass.contains( propertyName ) ) { + final XProperty property = propertyAnnotatedElement.getProperty(); + boolean hasIdAnnotation = hasIdAnnotation( property ); if ( !idPropertiesIfIdClass.isEmpty() && !isIgnoreIdAnnotations() - && hasIdAnnotation( propertyAnnotatedElement.getProperty() ) ) { + && hasIdAnnotation ) { missingEntityProperties.add( propertyName ); } else { boolean subclassAndSingleTableStrategy = inheritanceState.getType() == InheritanceType.SINGLE_TABLE && inheritanceState.hasParents(); + if ( !hasIdAnnotation && property.isAnnotationPresent( GeneratedValue.class ) ) { + throw new AnnotationException( + "Property '" + + BinderHelper.getPath( propertyHolder, propertyAnnotatedElement ) + + "' is annotated @GeneratedValue but is not part of an identifier" ); + } processElementAnnotations( propertyHolder, subclassAndSingleTableStrategy diff --git a/migration-guide.adoc b/migration-guide.adoc index 6d90b7ca69..d91cbdea9e 100644 --- a/migration-guide.adoc +++ b/migration-guide.adoc @@ -76,3 +76,27 @@ Finally, the `SelfRenderingFunctionSqlAstExpression.getRenderer()` method was de == Supported Dialects Please also do have a look at the link:{versionDocBase}/dialect/dialect.html[Supported Dialects] document to check for potential upgrades to the minimum version of the databases underpinning the dialects that Hibernate currently supports. + +[[GeneratedValues]] +== Generated Values + +Previous versions of Hibernate silently ignored annotations `@GeneratedValue` applied to non identifier fields. + +E.g. + +``` +@Entity +class Entity{ + + @Id + Integer id, + + + + @GeneratedValue // Ignored in Hibernate versions < 6.4, since 6.4 an AnnotationException is thrown + String name; +} + +``` + +From 6.4 this mapping is not allowed anymore and an `AnnotationException` will be raised.