java - @ElementCollection with Map<Entity, Embeddable> 其中 Entity 是 Embeddable 的字段

标签 java hibernate jpa map

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

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

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

Instrument 实体是:

@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,其中键是一个 Entity,它也作为 Embeddable 值的一个字段存在?如果是这样,我搞砸了什么。如果不是,最好的解决方法是使用 Instrument 实体的 ID 作为键吗?

提前致谢。

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

最佳答案

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?

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

@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

我已经能够坚持并正确检索包含此 map 的实体。

what am I screwing up.

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

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

关于java - @ElementCollection with Map<Entity, Embeddable> 其中 Entity 是 Embeddable 的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11974096/

相关文章:

java - Gradle 和用于 Android 构建的 Maven 存储库的悲伤

java - 外键未存储在子实体中(一对多)

"in subselect"的 hibernate 标准

java - OneToMany 映射中的旧数据被删除

java - SonarQube java.lang.ClassCastException : ParametrizedTypeJavaType cannot be cast to ParametrizedTypeJavaType

javascript - 无法在spring security中加载静态内容

java - 点击 Android/Java ListView 项时如何禁用点击声音?

java - 如何处理过时的连接?

java - Hibernate 未在不同架构上创建新列

java - Spring Hibernate 悲观锁