【问题标题】:How to use a child association property as a Map key in JPA parent entity如何在 JPA 父实体中使用子关联属性作为映射键
【发布时间】:2015-09-22 23:41:04
【问题描述】:

我有两个实体CarCarDescription,其中CarDescription 取决于表Language 中的另一个外键。

我想要完成的是在Car 中有一个HashMap,这样每当我有一个Car 实体对象时,我就可以从语言ID 访问所有描述。

实体Car.java

@Entity
@Table(name = "Car")
public class Car extends AbstractTimestampEntity implements Serializable {
    private static final long serialVersionUID = -5041816842632017838L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "ID", unique = true, nullable = false)
    private Long id;

    @OneToMany(mappedBy="car")
    @MapKeyColumn(name = "language_ID")
    // @MapKey(name = "language") // does not work either 
    private Map<Long, CarDescription> carDescription = new HashMap<>(0);
}

实体CarDescription.java

@Entity
@Table( name="car_description",
        uniqueConstraints = {
            @UniqueConstraint(columnNames={"language_id", "name"}) 
        }
)
public class CarDescription extends AbstractTimestampEntity implements Serializable {
    private static final long serialVersionUID = 2840651722666001938L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "ID", unique = true, nullable = false)
    private Long id;

    @NotNull
    @ManyToOne
    private Car car;

    @NotNull
    @OneToOne
    private Language language;

    // ..
}

实体Language.java

@Entity
public class Language implements Serializable {
    private static final long serialVersionUID = 3968717758435500381L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="ID")
    private Long id;

    // ..
}

我遇到的问题是映射为我提供了从每个 CarDescription.idCarDescription 的映射。

我怎样才能完成正确的映射?

【问题讨论】:

  • 为什么@MapKey(name = "language") 不适合你?
  • @DraganBozanovic 是一样的。我总是得到一张地图CarDescription.id -&gt; CarDescription,但我想要的是Language.id -&gt; CarDescription。我不知道,但@MapKey(name = "language") 不起作用.. :/
  • 好像被忽略了。进口好不好,是javax.persistence的注解吗?
  • @DraganBozanovic 是的,它来自javax.persistence。我尝试过的另一件事是@MapKeyColumn (name = "language_ID"),但这也不起作用,但在这种情况下,地图只是空的..不知道这里有什么不工作
  • 您尝试过将@MapKeyColumn@MapKey 一起使用还是不使用?

标签: java hibernate jpa orm hibernate-mapping


【解决方案1】:

CarDescription 中需要添加languageId 属性:

@Column(name = "language_id", insertable = false, updatable = false)
private Long languageId;

@NotNull
@OneToOne
@JoinColumn(name = "language_id")
private Language language;

public void setLanguage(Language language) {
    this.languageId = language.getId();
    this.language = language;
} 

然后你可以像这样在Car实体中使用它:

@OneToMany(mappedBy="car")
@MapKey(name = "languageId")
private Map<Long, CarDescription> carDescription = new HashMap<>(0);

【讨论】:

  • 嗨!感谢您的光临! :) 好吧,我已经尝试过了,但现在我在CarDescription 上得到org.hibernate.NonUniqueObjectException具有相同标识符值的不同对象已与会话相关联”。无法绕过它:/
  • 这与当前问题完全无关。当实体已与当前会话关联时,当您调用 Session.saveOrUpdate(entity) 时,可能会发生这种情况。您需要彻底检查您的持久性逻辑。
  • 看来问题确实来自@MapsId。创建声明现在给我primary key (language_ID),这不起作用。没有其他方法可以创建此映射吗?
  • 对,这仅适用于标识符。我将答案更改为使用insertable = false, updatable = false。检查更新版本。
  • 太棒了!非常感谢我不知道我是否会自己解决这个问题! Hibernate 的学习曲线非常平坦。^^
猜你喜欢
  • 1970-01-01
  • 2017-09-04
  • 2021-12-09
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 1970-01-01
  • 2021-07-13
相关资源
最近更新 更多