2010-05-21 15 views
21

Sto creando entità uguali per due tabelle diverse. Per fare mappature di tabelle, ecc. Diverse per le due entità, ma avere solo il resto del codice in un unico punto: una superclasse astratta. La cosa migliore sarebbe essere in grado di annotare elementi generici come i nomi di colonne (poiché saranno identici) nella super classe, ma questo non funziona perché le annotazioni JPA non sono ereditate da classi figlio. Ecco un esempio:È possibile aggiungere annotazioni JPA alle variabili di istanza di superclasse?

public abstract class MyAbstractEntity { 

    @Column(name="PROPERTY") //This will not be inherited and is therefore useless here 
    protected String property; 


    public String getProperty() { 
    return this.property; 
    } 

    //setters, hashCode, equals etc. methods 
} 

che vorrei di ereditare e specificare solo la roba specifici per i bambini, come le annotazioni:

@Entity 
@Table(name="MY_ENTITY_TABLE") 
public class MyEntity extends MyAbstractEntity { 

    //This will not work since this field does not override the super class field, thus the setters and getters break. 
    @Column(name="PROPERTY") 
    protected String property; 

} 

Tutte le idee o dovrò creare campi, getter e setter nelle classi bambino?

Grazie, Kris

risposta

24

Si potrebbe voler annotare MyAbstractEntity con la classe @MappedSuperclass in modo che Hibernate importerà la configurazione di MyAbstractEntity nel figlio e non sarà necessario sovrascrivere il campo, basta usare quello del genitore. Quell'annotazione è il segnale di ibernazione che deve esaminare anche la classe genitore. Altrimenti presume che possa ignorarlo.

+3

(nit-picking) ha detto nulla di ibernazione, è vero? egli può utilizzare un diverso provider JPA. ma ovviamente il tuo ragionamento si applica comunque –

+0

E in realtà sto usando l'ibernazione, ho semplicemente dimenticato di dirlo :) – Kristofer

2

Annotare la classe base con @MappedSuperclass dovrebbero fare esattamente quello che vuoi.

3

Mark superclasse come

@MappedSuperclass 

e rimuovere la proprietà dalla classe bambino.

12

Ecco un esempio con alcune spiegazioni che possono essere d'aiuto.

@MappedSuperclass:

  • è una classe convenienza
  • viene utilizzata per memorizzare stato condiviso & comportamento a disposizione classi figlie
  • Is not Persistable
  • Solo classi figlie sono persistibile

@Inheritance specifica una delle tre strategie di mappatura:

  1. Single-Table
  2. Iscritto
  3. tabella per ogni classe

@DiscriminatorColumn viene utilizzato per definire quale colonna verrà utilizzato per distinguere tra oggetti figlio.

@DiscriminatorValue viene utilizzato per specificare un valore utilizzato per distinguere un oggetto figlio.

I codice seguente genera il seguente:

enter image description here

Si può vedere che il campo id è in entrambe le tabelle, ma viene specificato solo nel AbstractEntityId @MappedSuperclass.

Inoltre, @DisciminatorColumn viene visualizzato come PARTY_TYPE nella tabella Party.

Il @DiscriminatorValue viene visualizzato come Persona come record nella colonna PARTY_TYPE della tabella Party.

Molto importante, la classe AbstractEntityId non viene persa affatto.

Non ho specificato le annotazioni @Column e invece mi baso solo sui valori predefiniti.

Se hai aggiunto un'entità organizzazione che si estendeva partito e se questo è stato persisteva prossimo, quindi la tabella di partito avrebbe:

  • id = 2
  • PARTY_TYPE = "Organizzazione"

La prima tabella della tabella Organizzazione avrebbe:

  • id = 2
  • altra valore di attributo associato in particolare con le organizzazioni
 

    @MappedSuperclass 
    @SequenceGenerator(name = "sequenceGenerator", 
      initialValue = 1, allocationSize = 1) 
    public class AbstractEntityId implements Serializable { 

     private static final long serialVersionUID = 1L; 

     @Id 
     @GeneratedValue(generator = "sequenceGenerator") 
     protected Long id; 

     public AbstractEntityId() {} 

     public Long getId() { 
      return id; 
     } 
    } 

    @Entity 
    @Inheritance(strategy = InheritanceType.JOINED) 
    @DiscriminatorColumn(name = "PARTY_TYPE", 
      discriminatorType = DiscriminatorType.STRING) 
    public class Party extends AbstractEntityId { 

     public Party() {} 

    } 

    @Entity 
    @DiscriminatorValue("Person") 
    public class Person extends Party { 

     private String givenName; 
     private String familyName; 
     private String preferredName; 
     @Temporal(TemporalType.DATE) 
     private Date dateOfBirth; 
     private String gender; 

     public Person() {} 

     // getter & setters etc. 

    } 

Spero che questo aiuti :)

Problemi correlati