2009-06-23 4 views
9

ho una gerarchia di classi:Qual è la corretta mappatura APP per @Id nel genitore e sequenza unica di classi base

abstract DomainObject { 
... 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SEQ") 
    @SequenceGenerator(name="SEQ",sequenceName="SEQ_DB_NAME") 
    @Column(name = "id", updatable = false, nullable = false) 
    private Long id; 
... 
} 

BaseClass extends DomainObject { 
... 
    // Fill in blank here where this class's @Id will use a unique sequence generator 
    // bonus points for any sort of automatic assignment of generator names that might 
    //prevent me from having to instrument all my domain objects uniquely 
... 
} 

note:

  • non ho specificamente bisogno di un generatore di classe di base , quindi se mi dovessi rimuovere senza problemi.
  • Questo è un db Oracle 9i, se questo è applicabile
  • Hibernate 3.4 JPA
  • Primavera 2.5 è disponibile pure

Grazie

risposta

8

Ok ecco come ho finito per risolvere il problema:

Classe base:

@MappedSuperclass 
public abstract class DomainObject implements Serializable { 
@Id 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SEQ") 
@Column(name = "id", updatable = false, nullable = false) 
private Long id; 

.. rest of class 
} 

classe discendente:

@Entity 
@SequenceGenerator(name="SEQ",sequenceName="SEQ_DB_NAME") 
public class BusinessObject extends DomainObject { 

... 

} 
+1

Credo che ciò funzionerebbe solo per la prima estensione di DomainObject all'interno della stessa unità di persistenza. Sul prossimo, in cui devi impostare il nome di SequenceGenerator per essere anche "SEQ", fallirebbe. Almeno questo è quello che il mio ha fatto usando il provider JPA di EclipseLink, e secondo il javadoc http://download.oracle.com/javaee/5/api/javax/persistence/SequenceGenerator.html il nome deve essere unico. – digitaljoel

+1

per chi guarda questo thread ... questo commento è il caso di OpenJPA 2.2. Non è possibile sovraccaricare il nome di SequenceGenerator. – DAJ

0

vi consiglio di utilizzare il tipo di ereditarietà riunite ai classe base. In questo modo tutti i campi comuni nella tabella di base e le personalizzazioni in tabelle specifiche. Ecco l'annotazione per questo:

@Inheritance(strategy=InheritanceType.JOINED) 

Una volta fatto ciò, si può tranquillamente utilizzare qualsiasi opzione di sequenziamento come tutti gli ID sono sempre sullo stesso tavolo. È possibile utilizzare una sequenza separata se si desidera ma non è supportata in tutti i fornitori di database. Immagino che non sia un problema dal momento che stai usando Oracle in particolare.

Ho usato questo e sembra funzionare bene.

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
private Long id; 
+0

È un po 'difficile dire che cosa l'intenzione di Nathan era dall'esempio, ma mi sono imbattuto in questa domanda perché sto migrando dai mapping Hibernate alle annotazioni JPA e tutto il mio ent ities estendono una classe base in modo da non dover definire un campo id, getter/setter, equals(), hashCode(), ecc. per ogni classe che voglio mantenere. Nel mio caso, sto usando l'ereditarietà per ridurre il codice boilerplate, ma non c'è in realtà alcuna eredità in corso dal punto di vista dei dati. In tal caso, @MappedSuperclass sarebbe davvero la soluzione preferita. – spaaarky21