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.

1
  • I bumped into this which in turn refers to this. Looks like I have no choice but to have multiple entity classes. Commented May 12, 2016 at 9:10

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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.
I haven't tried this myself yet, but after reading some threads (e.g. this one), 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.