hibernate/hibernate-orm · error · AnnotationException
@GeneratedValue annotation specified 'strategy=${generationT
Error message
@GeneratedValue annotation specified 'strategy=${generationType}' and 'generator' but the generator name is unnecessary What it means
IdentifierGeneratorDefinition.buildIdentifierGenerator throws AnnotationException when @GeneratedValue combines GenerationType.IDENTITY or GenerationType.UUID with a non-empty generator name. For these strategies Hibernate derives the generator entirely from the strategy, so a named generator is meaningless and is rejected as a mapping error rather than ignored.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/IdentifierGeneratorDefinition.java:112
@Internal
public static IdentifierGeneratorDefinition createImplicit(
String name,
TypeDetails idType,
String generatorName,
GenerationType generationType) {
// If we were unable to locate an actual matching named generator assume
// a sequence/table of the given name, make one based on GenerationType.
return switch ( generationType == null ? GenerationType.SEQUENCE : generationType ) {
case SEQUENCE -> buildSequenceGeneratorDefinition( name );
case TABLE -> buildTableGeneratorDefinition( name );
case AUTO -> new IdentifierGeneratorDefinition(
name,
generatorStrategy( generationType, generatorName, idType ),
singletonMap( IdentifierGenerator.GENERATOR_NAME, name )
);
case IDENTITY, UUID -> throw new AnnotationException(
"@GeneratedValue annotation specified 'strategy=" + generationType
+ "' and 'generator' but the generator name is unnecessary"
);
};
}
private static IdentifierGeneratorDefinition buildTableGeneratorDefinition(String name) {
final TableGeneratorJpaAnnotation tableGeneratorUsage = TABLE_GENERATOR.createUsage( null );
if ( isNotEmpty( name ) ) {
tableGeneratorUsage.name( name );
}
final Builder builder = new Builder();
interpretTableGenerator( tableGeneratorUsage, builder );
return builder.build();
}
private static IdentifierGeneratorDefinition buildSequenceGeneratorDefinition(String name) {
final SequenceGeneratorJpaAnnotation sequenceGeneratorUsage = SEQUENCE_GENERATOR.createUsage( null );View on GitHub (pinned to fad1729dce)
Solutions
- Delete the generator attribute for IDENTITY and UUID strategies
- If you actually want a named generator, switch the strategy to SEQUENCE/TABLE and define it (@SequenceGenerator/@TableGenerator or generator definition)
- Audit other entities for the same pattern — one fixed annotation usually means siblings have it too
Example fix
// before @Id @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "item_gen") private Long id; // after @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
Defensive patterns
Strategy: validation
Validate before calling
for (Field f : entity.getDeclaredFields()) {
GeneratedValue gv = f.getAnnotation(GeneratedValue.class);
if (gv != null && !gv.generator().isEmpty()
&& (gv.strategy() == GenerationType.IDENTITY || gv.strategy() == GenerationType.UUID)) {
throw new IllegalStateException("@GeneratedValue on " + f + " must not name a generator for " + gv.strategy());
}
} Try / catch
catch (AnnotationException e) {
throw new IllegalStateException("Remove the generator attribute from @GeneratedValue(strategy=IDENTITY/UUID) ids", e);
} Prevention
- Write a build-time ArchUnit/reflection test enforcing the rule across all entities
- Do not copy @GeneratedValue blocks between sequence and identity entities
When it happens
Trigger: An entity or mapped-superclass id annotated like @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "myGen") or @GeneratedValue(strategy = GenerationType.UUID, generator = "uuidGen"). The code path runs when no registered generator definition with that name exists, so Hibernate tries to fabricate one from the strategy and hits the forbidden combination.
Common situations: Copy-paste from sequence-style entities; generators templated by code generators (JHipster-likes, internal scaffolds) that always emit a generator name; code migrated from older Hibernate versions that silently tolerated the extra attribute.
Related errors
- Class '<componentClassName>' is an '@Embeddable' type and ma
- Property '<propertyName>' may not be annotated '@BatchSize'
- One to many association '<propertyName>' was annotated '@Col
- Collection '<propertyName>' was annotated '@Collate'
- Root entity '<entityName>' is annotated '@DiscriminatorOptio
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/cb68d02cc29c7734.
Report an issue: GitHub.