Java @元素集合与地图<;实体,可嵌入>;其中实体是可嵌入的字段

Java @元素集合与地图<;实体,可嵌入>;其中实体是可嵌入的字段,java,hibernate,jpa,map,Java,Hibernate,Jpa,Map,在搜索了JPA文档和各种帖子之后,我对JPA2.0是否可以实现以下内容感到困惑。我刚开始学JPA所以如果我做了什么蠢事请原谅 我的领域模型有一个“投资组合”,其中包含零个或多个“未平仓”。头寸由“工具”(JPA实体)和价格(双倍)组成。投资组合如下: @Entity (name = "portfolio") public class Portfolio { @Id @Column (name = "id") @GeneratedValue private long

在搜索了JPA文档和各种帖子之后,我对JPA2.0是否可以实现以下内容感到困惑。我刚开始学JPA所以如果我做了什么蠢事请原谅

我的领域模型有一个“投资组合”,其中包含零个或多个“未平仓”。头寸由“工具”(JPA实体)和价格(双倍)组成。投资组合如下:

@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>();
....
@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;
....
而该工具实体为:

@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();
    ....
当我尝试使用它时,模式被创建,并且我能够持久化公文包,但是当尝试检索它们时,我在Instrument类的hashCode方法中得到一个NullPointerException。JPA似乎正在尝试获取哈希代码来构建映射键,但尚未加载Instrument对象

通过调试,我可以看出,尽管在Instrument对象中设置了id,但所有其他字段都是空的

所以我的问题是,JPA2.0是否允许一个ElementCollection,其中键是一个实体,也作为一个可嵌入值字段出现?如果是的话,我搞砸了什么。如果不是,最好的解决方法是使用仪器实体的id作为键吗

提前谢谢

p、 我正在使用Hibernate4.1.4JPA实现

所以我的问题是,JPA2.0是否允许一个ElementCollection,其中键是一个实体,也作为一个可嵌入值字段出现

是的,我用这个映射成功地做到了:

@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;
@ElementCollection(targetClass=FreightBid.class)
@MapKeyJoinColumn(name=“carrier\u id”,referencedColumnName=“id”)
@收款表(name=“运费\投标”,
joinColumns=@JoinColumn(name=“offer\u pool\u id”))
@访问权限(AccessType.FIELD)
私人地图bidsByCarrier;
在我的例子中,开利是一个
@实体
,而FreightBid是一个
@嵌入式

我已经能够正确地保存和检索包含此映射的实体

我搞砸了什么

应移除受保护的仪表的字段
来自
OpenPosition
类,而是使用公文包类中map字段上的注释
@MapKeyJoinColumn
来声明哪个列应该用作map键的连接列


此外,最好避免在作为映射键的对象的hashCode方法中使用id以外的其他字段。。。您的JPA实现者可能会把事情搞砸。

AFAIK您不能在嵌入式系统中使用实体。可嵌入文件应仅包含基类型。也不要在实体中使用
HashMap
,而是使用接口
Map
。顺便说一句,欢迎来到stackoverflow;-)@siebz0r感谢您的回馈和欢迎。我相信这对于JPA1.0来说是正确的,在JPA1.0中只允许基本映射,但JPA2.0表明可嵌入对象允许所有关系-请参阅。回复:
Map
vs
HashMap
,我不知道你的意思。该字段确实具有类型
Map
,但在实例化它时,我必须使用一个具体的类(即
HashMap