当前位置: 首页 > 知识库问答 >
问题:

@ElementCollection带有Map,其中Entity是可嵌入

邬楚青
2023-03-14

在搜索了JPA文档和各种帖子后,我很困惑以下内容是否适用于JPA2。我刚开始学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
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();
    ....

当我试图使用这个时,模式被创建,我能够持久化投资组合,但是当我试图检索它们时,我在仪器类的hashCode方法中得到了一个NullPointerExctive,看起来JPA正在试图获取哈希代码来构建Map键,但是仪器对象没有被加载。

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

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

提前谢谢。

p、 我正在使用hibernate 4.1.4 JPA实现。

共有1个答案

东明德
2023-03-14

所以我的问题是,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;

在我的例子中,开利是一个@实体,而FreightBid是一个@嵌入式

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

我搞砸了什么?

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

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

 类似资料:
  • 我有一个相当典型的场景,其中有一个main@实体,他内部的所有内容都是可嵌入的(因此,没有父实体,内部的所有内容都没有意义)。现在JPA 2.0阻止我在另一个@ElementCollection中定义的@Embeddeble中嵌套一个@ElementCollection: JSR-317 2.6可嵌入类和基本类型的集合包含在元素集合中的可嵌入类(包括另一个可嵌入类中的可嵌入类)不得包含元素集合,也

  • 我正在尝试查找相关的JPA文档,但很难找到任何指定是否允许我创建实体的ElementCollection的内容。我知道典型的用法是将@Embedded的@ElementCollection制作成一个@ElementCollection,但由于我遇到了一个Hibernate bug,我需要将我的可嵌入类制作成它自己的实体。 我希望实体的生命周期由父类控制。因此,我希望不要为新实体创建任何DAO/存储

  • 问题内容: 我正在运行Hibernate 4.2.6.Final / JPA2,并尝试具有@Embeddable对象的@ElementCollection列表,这些对象本身包含String的@ElementCollection列表。 但是,hibernate在尝试实例化EntityManager时抛出ConcurrentModificationException,我根本不了解。 如果我注释掉in

  • mapMap.map(i => i * 30); const mapReduce = Immutable.Map({ a: 10, b: 20, c: 30 });

  • 我遇到了一个问题,在我的JPA表中没有任何内容被持久化。据我所知,我想我理解了的基本思想。我猜出现问题的原因是,我在一个可嵌入的对象中有一个。 一个简单的例子: 有什么线索表明可能出了什么问题吗? 为了简洁起见,我将尽量使附加信息尽可能简短。 创建计算原因 创建计算历史记录 调试信息在计算历史#创建 HibernateDAO仓库 Hibernate生成的SQL 看起来HiberNate甚至没有生成

  • null ServerEndpoint: 谢谢你。