2016-05-12 3 views
0

Hier ist das Problem, das ich habe:JPA: dynamisch eine Entitätszuordnung auf einer Tabelle basiert auf einer Instanzvariablen

class CurrencyPrice { 
    @Transient 
    String pair; 
    float spotPrice; 
    Date timeStamp; 
} 

Und ich habe 3-Tabelle, deren Namen für „usd Wert von Euro/gbp stehen/Yen jeweils ": usd_euro, usd_gbp & usd_yen. Sie haben alle die gleichen 3 Spalten: id, spotprice, timestamp.

Aus irgendeinem Grund kann ich keine einzige Tabelle haben. Die transiente Instanz-Variable ‚Paar‘ besitzen die folgenden Werte je nachdem, was es bedeutet: „usd_euro“, „usd_gbp“ & „usd_yen“

  1. Und je nach dem Wert in ‚Paar‘ Ich möchte ein einfügen Zeile in einer der Tabellen, zB: wenn ich den Wert "usd_yen" in "Paar" habe, dann sollte das Objekt in der Tabelle usd_yen persistent sein.

  2. Und wenn ich Daten holen, ich will JPA entscheiden, welche Tabelle zur Auswahl basierend auf dem Wert in ‚Paar‘

Das ist einfach in JDBC aber ist es eine Möglichkeit, zu tun das in JPA?

Vielen Dank.

+0

Ich stieß [das] (http://stackoverflow.com/questions/3505866/how-to-map-one-class-to-different-tables-using-hibernate-jpa-annotations) was wiederum verweist zu [dies] (http://stackoverflow.com/questions/997203/jpa-how-to-use-the-same-class-entity-to-map- different- tables). Sieht so aus, als hätte ich keine andere Wahl, als mehrere Entity-Klassen zu haben. – kskblr07

Antwort

1

Wenn ich Ihre Anforderungen richtig verstanden habe, das ist eigentlich könnte jetzt in JPA machbar sein (diese Themen Sie zitieren sind ziemlich alt), wenn Sie und wenn es akzeptabel ist Vererbung auf Ihrer Einheit und eine Join-Tabelle zusätzlich nutzen können dass die ID für jeden Typ nicht zusammenhängend ist.

Sie könnten im Grunde Ihre Klassen wie diese dann definieren:

@Entity 
@Table(name="curr_base") // choose a suitable name 
@Inheritance(strategy=InheritanceType.JOINED) 
@DiscriminatorColumn(name="currency", discriminatorType=DiscriminatorType.STRING) // your join table needs this column in addition to the id 
public abstract class CurrencyPrice { 
    @Id 
    private int id; 
} 

@Entity 
@Table(name="usd_euro") 
@DiscriminatorValue("usd_euro") 
public class UsdEuroPrice extends CurrencyPrice { 
    float spotPrice; 
    Date timeStamp; 
} 

@Entity 
@Table(name="usd_gbp") 
@DiscriminatorValue("usd_euro") 
public class UsdGbpPrice extends CurrencyPrice { 
    float spotPrice; 
    Date timeStamp; 
} 

@Entity 
@Table(name="usd_yen") 
@DiscriminatorValue("usd_euro") 
public class UsdYenPrice extends CurrencyPrice { 
    float spotPrice; 
    Date timeStamp; 
} 

I spotPrice und timeStamp auf jeder Unterklasse repliziert, so dass Sie zu Ihren bestehenden Tabellendefinitionen nicht ändern - natürlich wäre es viel sauberer sein um sie nur in der Superclass/Join-Tabelle zu haben.

Diese Zuordnung ermöglicht es beispielsweise, eine EntityManager.persist(new UsdGbpPrice(...)) durchzuführen und JPA eine Zeile in die rechte Tabelle einzufügen. Weitere Informationen finden Sie unter here.

+0

Hallo Hein Blöd, vielen Dank für die ausführliche Antwort. Kommen Sie zum letzten Teil Ihrer Antwort, ist es möglich GenericEntityManager.persist (CurrencyPrice) anstelle von UsdGbpPrice? Es wird versucht, Entity-Typ (Währungspaar) spezifische Fetch/Persist-Funktionen zu vermeiden. Tatsächlich erzeugt NetBeans Entity-spezifische JPA-Controller - ich versuche, an dem generischen zu arbeiten. Es wäre schön, wenn ich dies tun könnte: GenericEntityManager.persist (CurrencyPrice) und es intern herausfindet, in welcher Tabelle der CurriculumPrice beibehalten werden soll, ohne dass ich Code für jeden Entitätstyp schreiben/generieren/pflegen muss. – kskblr07

+0

Ich habe das selbst noch nicht versucht, aber nachdem ich einige Threads gelesen habe (zB [diese] (http://stackoverflow.com/questions/8119678/jpa-entity-inheritance-with-abstract-classes-constrainviolationexception), Ich bin mir sicher, dass es funktionieren sollte. Sie müssen offensichtlich nur eine der konkreten Unterklassen an einem Punkt instanziieren, die Sie dann einem Feld zuordnen können, das mit dem abstrakten Supertyp deklariert ist. Dieses Feld kann dann an Ihren GenericEntityManager übergeben werden. –

Verwandte Themen