一尘不染

如何在JPA父实体中将子关联属性用作Map键

hibernate

我有两个实体Car,它CarDescription在哪里CarDescription取决于表中的另一个外键Language

我要完成的工作是拥有一个HashMapin,Car这样每当我有一个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;

    // ..
}

实体 语言.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.id到的映射CarDescription

如何完成正确的映射?


阅读 235

收藏
2020-06-20

共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);
2020-06-20