【问题标题】:@ElementCollection with Map<Entity, Embeddable> where Entity is a field of the Embeddable@ElementCollection 与 Map<Entity, Embeddable> 其中 Entity 是 Embeddable 的一个字段
【发布时间】:2012-08-12 00:44:57
【问题描述】:

在搜索了 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>();
....

OpenPosition Embeddable 如下:

@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 似乎正在尝试获取哈希码来构建 Map 键,但 Instrument 对象尚未加载。

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

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

提前致谢。

附言我正在使用 hibernate 4.1.4 JPA 实现。

【问题讨论】:

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

标签: java hibernate jpa map


【解决方案1】:

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

是的,我设法用这个映射做到了:

@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;

就我而言,Carrier 是 @Entity,FreightBid 是 @Embedded

我已经能够正确地持久化和检索包含此映射的实体。

我在搞砸什么。

您应该从OpenPosition 类中删除字段protected Instrument instrument;,而是在Portfolio 类的映射字段上使用注释@MapKeyJoinColumn 来声明应该将哪个列用作映射键的连接列。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-05
    • 2012-09-25
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多