2009-05-07 3 views
9

Ho uno schema precedente che non può essere modificato. Sto usando una classe base per le funzionalità comuni e contiene un oggetto incorporato. Esiste un campo che viene normalmente mappato nell'oggetto incorporato che deve essere presente nell'ID di persistenza solo per una (di molte) sottoclassi. Ho creato una nuova classe id che la include ma poi ho l'errore che il campo è mappato due volte. Ecco qualche esempio di codice che è molto semplificata per mantenere la sanità mentale del lettore:Come rendere un campo mappato ereditato da un transiente di superclasse in JPA?

@MappedSuperclass 
class BaseClass { 
    @Embedded 
    private Data data; 
} 

@Entity 
class SubClass extends BaseClass { 
    @EmbeddedId 
    private SubClassId id; 
} 

@Embeddable 
class Data { 
    private int location; 

    private String name; 
} 

@Embeddable 
class SubClassId { 
    private int thingy; 

    private int location; 
} 

ho provato @AttributeOverride ma posso solo farlo per rinominare il campo. Ho provato a impostarlo su updatable = false, insertable = false, ma questo non sembra funzionare se usato nell'annotazione @AttributeOverride. Vedere la risposta sotto per la soluzione a questo problema.

Mi rendo conto che potrei cambiare la classe base ma non voglio dividere l'oggetto incorporato per separare il campo condiviso in quanto renderebbe il codice circostante più complesso e richiederà un brutto codice di avvolgimento. Potrei anche ridisegnare l'intero sistema per questo caso d'angolo, ma in realtà preferirei non farlo.

Sto utilizzando Hibernate come provider JPA.

risposta

5

Ho trovato la ragione che AttributeOverride non funzionava. Quando annoti la classe devi includere l'identificatore dell'oggetto incorporato nel campo del nome. Stavo facendo questo:

@Entity 
@AttributeOverride(name = "location", column = @Column(name = "location", insertable = false, updatable = false) 
class SubClass extends BaseClass { 

Quando aveva bisogno di essere questo:

@Entity 
@AttributeOverride(name = "data.location", column = @Column(name = "location", insertable = false, updatable = false) 
class SubClass extends BaseClass { 

cosa strana è che la modifica campo il nome di @ Colonna ha fatto il lavoro con la prima versione, ma l'inseribile e campi aggiornabili sono stati ignorati . Non so se questo sia un bug o una sottigliezza delle specifiche JPA.

In ogni caso, questo risolve il modo di rendere il campo di sola lettura ma non risponde alla domanda originale: è possibile creare un campo da un transiente mappato della superclasse?

+0

So che ora ha 6 anni, ma hai mai trovato una soluzione a questa domanda? E/o ricorda cos'era? –

+0

@EricB. Spiacente, non ho mai trovato un modo per non ereditare un campo mappato. Non credo sia possibile farlo. Penso che potrebbero vederlo come cercare di ridurre la visibilità di un metodo ereditato in Java, quindi solo contro le regole. Nel mio caso ho lavorato intorno all'astuccio che è un po 'brutto ma era l'unica opzione. –