【发布时间】: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。回复:
MapvsHashMap,我不确定你的意思。该字段确实具有Map类型,但是在实例化它时,我必须使用具体类(即HashMap)