After searching through the JPA docs and various posts, I'm confused as to whether the following is possible with JPA2.0. I'm just starting out with JPA so excuse me if I'm doing something stupid,
My domain model has a "Portfolio", which contains zero or more "open positions". A position consists of an "Instrument" (which is a JPA Entity) and a price (double). The portfolio is as follows:
@Entity (name = "portfolio")
public class Portfolio {
@Id
@Column (name = "id")
@GeneratedValue
private long id;
@ElementCollection (fetch = FetchType.EAGER)
@CollectionTable (name = "portfolio_entry", joinColumns = @JoinColumn (name = "portfolio_id"))
private final Map<Instrument, OpenPosition> positions = new HashMap<Instrument, OpenPosition>();
....
The OpenPosition Embeddable is as follows:
@Embeddable
public class OpenPosition extends Position {
@ManyToOne (targetEntity = InstrumentImpl.class, optional = false)
@JoinColumn (name = "instrument_id", nullable = false)
protected Instrument instrument;
@Column (name = "price", nullable = false)
protected double price;
....
and the Instrument entity is:
@Entity (name="instrument")
public class Instrument {
@Id
@Column(name = "id")
@GeneratedValue
private long id;
@Column(name = "isin", nullable = false)
private String isin;
....
@Override
public int hashCode() {
int hash = 17;
hash = 31 * hash + isin.hashCode();
....
When I try to use this, the schema is created and I am able to persist portfolios, but when trying to retrieve them, I get a NullPointerException in the hashCode method of the Instrument class. It seems JPA is trying to get the hash code to build the Map key, but the Instrument object has not been loaded.
I can see through debugging that although the id is set in the Instrument object, all the other fields are null.
So my question is, does JPA2.0 allow an ElementCollection where the key is an Entity that is also present as a field of the Embeddable value? If so, what am I screwing up. And if not, is the best workaround to use the id of the Instrument entity as the key instead?
Thanks in advance.
p.s. I'm using the hibernate 4.1.4 JPA implementation.
So my question is, does JPA2.0 allow an ElementCollection where the key is an Entity that is also present as a field of the Embeddable value?
Yes, i managed to do it with this mapping:
@ElementCollection( targetClass = FreightBid.class )
@MapKeyJoinColumn( name = "carrier_id", referencedColumnName = "id" )
@CollectionTable( name = "freight_bid",
joinColumns = @JoinColumn( name = "offer_pool_id" ) )
@Access( AccessType.FIELD )
private Map<Carrier,FreightBid> bidsByCarrier;
In my case, Carrier is an @Entity
and FreightBid is an @Embedded
I've been able to persist and retrieve the Entity that contains this map correctly.
what am I screwing up.
You should remove the field protected Instrument instrument;
from OpenPosition
class and instead use the annotation @MapKeyJoinColumn
on the map field in Portfolio class to declare wich column should be used as join column to the map key.
Also it would be best to avoid using other fields than id in the hashCode method of an object wich act as a map key... you JPA implementor might screw things up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With