@ElementCollection with Map< Entity,Embeddable>其中Entity是Embeddable的一个字段 [英] @ElementCollection with Map<Entity, Embeddable> where Entity is a field of the Embeddable

查看:191
本文介绍了@ElementCollection with Map< Entity,Embeddable>其中Entity是Embeddable的一个字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在查阅JPA文档和各种帖子之后,我很困惑JPA2.0是否可以实现以下功能。我刚刚开始使用JPA,所以如果我做了一些愚蠢的事情,请原谅我。



我的域模型有一个Portfolio,其中包含零个或多个open位置。一个职位由一个工具(这是一个JPA实体)和一个价格(双重)组成。组合如下:

  @Entity(name =portfolio)
public class Portfolio {
@Id
@Column(name =id)
@GeneratedValue
私人长ID;

@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name =portfolio_entry,joinColumns = @JoinColumn(name =portfolio_id))
private final Map<仪器,OpenPosition> positions = new HashMap< Instrument,OpenPosition>();
....

OpenPosition Embeddable如下:

  @Embeddable 
public class OpenPosition extends Position {
@ManyToOne(targetEntity = InstrumentImpl.class,optional = false)
@JoinColumn(name =instrument_id,nullable = false)
受保护的乐器乐器;

@Column(name =price,nullable = false)
保护双重价格;
....

以及Instrument实体为:

  @Entity(name =instrument)
public class Instrument {
@Id
@Column(name = ID)
@GeneratedValue
私人长ID;

@Column(name =isin,nullable = false)
private String isin;
....
@Override
public int hashCode(){
int hash = 17;
hash = 31 * hash + isin.hashCode();
....

当我尝试使用这个时,我能够坚持投资组合,但是当试图检索它们时,我在Instrument类的hashCode方法中得到一个NullPointerException异常。看起来JPA试图获取哈希代码来构建Map键,但Instrument对象尚未加载。



通过调试我可以看出,虽然id是设置在Instrument对象中,所有其他字段都为null。

所以我的问题是,JPA2.0是否允许一个ElementCollection,其中键是一个也存在的实体作为Embeddable值的字段?如果是这样,我搞砸了什么。如果没有,最好的解决方法是使用Instrument实体的ID作为密钥吗?



预先感谢。



ps我使用hibernate 4.1.4 JPA实现。

解决方案


所以我的问题是, JPA2.0允许一个ElementCollection,其中的键是一个也作为Embeddable值的字段存在的实体?


是的,我设法用这个映射来做到这一点:

<$ p $
@CollectionTable(name =freight_bid,$ p $ @ElementCollection(targetClass = FreightBid.class)
@MapKeyJoinColumn(name =carrier_id,referencedColumnName =id b $ b joinColumns = @JoinColumn(name =offer_pool_id))
@Access(AccessType.FIELD)
私人地图< Carrier,FreightBid> bidsByCarrier;

在我的例子中,Carrier是一个 @Entity 和FreightBid是 @Embedded



我已经能够坚持并检索包含此映射的实体


我搞砸了什么。


您应该从 OpenPosition 类中移除字段 protected instrument instrument; ,而使用注释 @MapKeyJoinColumn 在Portfolio类的地图字段中声明至少应该用作地图键的连接列。



最好避免在对象的hashCode方法中使用除id之外的其他字段作为映射键......您的JPA实现者可能会搞砸了。


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.

这篇关于@ElementCollection with Map&lt; Entity,Embeddable&gt;其中Entity是Embeddable的一个字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆