0

Here is the problem i have:

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

And I have 3 table the names of which stand for "usd value of euro/gbp/yen respectively": usd_euro, usd_gbp & usd_yen. They all have the same 3 columns: id, spotprice, timestamp.

For some reason i cannot have a single table. The transient instance variable 'pair' will have the following values depending on what it represents: "usd_euro", "usd_gbp" & "usd_yen"

  1. And depending on the value in 'pair' I want to insert a row in one of the tables, eg: if I have the value "usd_yen" in 'pair' then the object should be persisted in usd_yen table.

  2. And when I want to fetch data, I want JPA to decide which table to SELECT from based on the value in 'pair'

This is simple in JDBC but is there a way to do this in JPA?

Thank you.

kskblr07
  • 3
  • 1
  • 3
  • I bumped into [this](http://stackoverflow.com/questions/3505866/how-to-map-one-class-to-different-tables-using-hibernate-jpa-annotations) which in turn refers to [this](http://stackoverflow.com/questions/997203/jpa-how-to-use-the-same-class-entity-to-map-different-tables). Looks like I have no choice but to have multiple entity classes. – kskblr07 May 12 '16 at 09:10

1 Answers1

1

If I understand your requirements correctly, this might actually be feasible in JPA now (those threads you cite are quite old), if you can use inheritance on your entity and an additional join table and if it's acceptable that the ID for each type is not contiguous.

You could basically define your classes like this then:

@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 replicated spotPrice and timeStamp on each subclass so that you don't have to modify your existing table definitions - of course it would be much cleaner to only have them on the superclass/join table.

This mapping allows it for example to perform a EntityManager.persist(new UsdGbpPrice(...)) and have JPA insert a row into the right table. For more information, look here.

Hein Blöd
  • 1,553
  • 1
  • 18
  • 25
  • Hi Hein Blöd, Thank you for the detailed response. Coming to the last part of your answer, is it possible to have GenericEntityManager.persist(CurrencyPrice) instead of UsdGbpPrice? Trying to avoid entity-type (currency-pair) specific fetch/persist functions. In fact NetBeans generates Entity specific JPA controllers - I am trying to work on the generic one. It would be nice if i can do this: GenericEntityManager.persist(CurrencyPrice) and it internally figures out which table the CurrencyPrice should be persisted in, without me having to write/generate/maintain code for each entity type. – kskblr07 May 18 '16 at 20:02
  • I haven't tried this myself yet, but after reading some threads (e.g. [this one](http://stackoverflow.com/questions/8119678/jpa-entity-inheritance-with-abstract-classes-constrainviolationexception)), I'm sure that it should work. You obviously just have to instantiate one of the concrete subclasses at one point, which you can then assign to a field declared with the abstract supertype. That field can then be passed to your GenericEntityManager. – Hein Blöd May 19 '16 at 09:25