2009-05-07 7 views
9

Ich habe ein Legacy-Schema, das nicht geändert werden kann. Ich verwende eine Basisklasse für die gemeinsamen Funktionen und es enthält ein eingebettetes Objekt. Es gibt ein Feld, das normalerweise dem eingebetteten Objekt zugeordnet wird, das für nur eine (von vielen) Unterklassen in der Persistenz-ID enthalten sein muss. Ich habe eine neue ID-Klasse erstellt, die es enthält, aber dann bekomme ich den Fehler, dass das Feld zweimal zugeordnet ist. Hier ist ein Beispiel-Code, der stark vereinfacht wird, um die geistige Gesundheit des Lesers zu halten:Wie erstelle ich ein zugeordnetes Feld, das von einem Superklassen-Transient in JPA übernommen wurde?

@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; 
} 

ich versucht habe @AttributeOverride aber ich kann es nur das Feld umbenennen bekommen. Ich habe versucht, es auf update = false, insertable = false zu setzen, aber dies schien nicht zu funktionieren, wenn es in der @AttributeOverride Annotation verwendet wurde. Siehe die Antwort unten für die Lösung dieses Problems.

Ich weiß, dass ich die Basisklasse ändern konnte, aber ich möchte das eingebettete Objekt wirklich nicht trennen, um das geteilte Feld zu trennen, da es den umgebenden Code komplexer machen würde und etwas hässlichen Umbruchcode erfordern würde. Ich könnte das ganze System für diesen Eckfall auch neu entwerfen, aber ich würde wirklich eher nicht.

Ich verwende Hibernate als JPA-Anbieter.

Antwort

5

Ich habe Grund gefunden AttributOverride hat nicht funktioniert. Wenn Sie die Klasse mit Anmerkungen versehen, müssen Sie den Bezeichner des eingebetteten Objekts in das Namensfeld einschließen. Ich tat dies:

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

Wenn es notwendig, um dies zu sein:

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

Merkwürdige ist, dass die @ Column Name Feld ändern tat Arbeit mit der ersten Version, aber die einführbare und aktualisierbar Felder wurden ignoriert . Ich weiß nicht, ob das ein Bug oder eine Subtilität der JPA-Spezifikation ist.

Wie auch immer, dies löst, wie das Feld schreibgeschützt gemacht wird, aber es beantwortet nicht die ursprüngliche Frage: Ist es möglich, ein Feld aus einem zugeordneten Superklassen-Transient zu machen?

+0

Ich weiß, das ist jetzt 6 Jahre alt, aber hast du jemals eine Lösung für diese Frage gefunden? Und/oder erinnern, was es war? –

+0

@EricB. Entschuldigung, habe nie eine Möglichkeit gefunden, ein zugeordnetes Feld nicht zu übernehmen. Ich glaube nicht, dass es möglich ist. Ich denke, sie sehen es vielleicht so, als würden sie versuchen, die Sichtbarkeit einer geerbten Methode in Java zu reduzieren - also gerade gegen die Regeln. In meinem Fall arbeitete ich um die Ecke, die ein bisschen hässlich ist, aber die einzige Option war. –