@SequenceGenerator sulla class annotata con @MappedSuperclass

Ho la seguente struttura delle mie quadro:

@MappedSuperclass public abstract class BaseEntity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqGenerator") private Long id; } @MappedSuperclass @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @SequenceGenerator(name = "seqGenerator", sequenceName = "DICTIONARY_SEQ") public abstract class Intermed extends BaseEntity {} @Entity public class MyEntity1 extends Intermed {} @Entity public class MyEntity2 extends Intermed {} 

E ho ottenuto la seguente eccezione:

  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [context/applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unknown Id.generator: seqGenerator 

Quando cambio @MappedSuperclass in @Entity nella class Intermed, tutto funziona correttamente. Ci sono problemi con l’utilizzo di @MappedSuperclass e @SequenceGenerator? O mi sono perso qualcosa?

Ecco cosa dice la specifica JPA 1.0 sull’annotazione SequenceGenerator :

9.1.37 Annotazione SequenceGenerator

L’annotazione SequenceGenerator definisce un generatore di chiavi primario a cui può essere fatto riferimento per nome quando viene specificato un elemento generatore per l’annotazione GeneratedValue . Un generatore di sequenze può essere specificato nella class quadro o nel campo o proprietà chiave primaria . L’ambito del nome del generatore è globale rispetto all’unità di persistenza (su tutti i tipi di generatore).

E una superclass mappata non è un’ quadro. Quindi, secondo il modo in cui leggo le specifiche, ciò che vuoi fare non è ansible. O rendi la class Intermed un’ quadro o metti il SequenceGenerator nelle sottoclassi.

Mi sono imbattuto nello stesso problema descritto in questa domanda mentre cercavo di ottenere generatori di ID applicazione larghi.

La soluzione è in realtà nella prima risposta: mettere il generatore di sequenze sul campo chiave primaria .

Così:

 @MappedSuperclass public abstract class BaseEntity { @Id @SequenceGenerator(name = "seqGenerator", sequenceName = "DICTIONARY_SEQ") @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqGenerator") private Long id; } @MappedSuperclass @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public abstract class Intermed extends BaseEntity {} @Entity public class MyEntity1 extends Intermed {} @Entity public class MyEntity2 extends Intermed {} 

Mentre fare le cose in questo modo sembra straordinariamente stupido (almeno per me) funziona.