我有一个@Entity
类,在同一字段上带有@Id
注释和@OneToOne
注释。通常这不是问题,但是带有这些注释的字段的实体类使用复合键。这导致比我预期的要复杂的多。
这里是引起问题的实体类:
@Entity
public class ReportDetails implements Serializable {
@Id
@OneToOne
private MachineLine machineLine;
}
这是MachineLine
实体类,在ReportDetails
中被用作ID:
@Entity
@IdClass(MachineLine.MachineLineKey.class)
public class MachineLine {
@Id
@ManyToOne
private Machine machine;
@Id
private long lineIndex;
public static class MachineLineKey implements Serializable {
private Machine machine;
private long lineIndex;
}
}
为了节省空间,我从这些类定义中省略了任何多余的字段以及getter和setter方法。
当我尝试运行我的应用程序时,它给出以下异常:
java.lang.IllegalArgumentException: This class [class ReportDetails] does not define an IdClass
[当我在@IdClass
上放置ReportDetails
批注时,它需要定义我在@IdClass
中定义的任何类的单个字段,就像在MachineLine
中一样。但是,我尝试避免这样做,而是希望每当从数据库中检索到MachineLine
实体时都返回整个ReportDetails
实体。
是否有一种方法可以使MachineLine
作为ReportDetails
的ID字段,而不必在ReportDetails
中定义额外的字段?
这就是JPA所谓的“派生身份”。您可以尝试如下操作:
ReportDetails:
@Entity
public class ReportDetails implements Serializable {
// all attributes map by the relationship: AttributeOverride is not allowed
@EmbeddedId
private MachineLine.Id id;
@MapsId
@JoinColumns({
@JoinColumn(name="machineId", referencedColumnName="machineId"),
@JoinColumn(name="machineLineIndex", referencedColumnName="index")
})
@OneToOne
private MachineLine machineLine;
// ...
}
MachineLine:
@Entity
public class MachineLine {
@EmbeddedId
private Id id;
@MapsId("machineId") // maps machineId attribute of embedded id
@ManyToOne
private Machine machine;
// ...
@Embeddable
public static class Id implements Serializable {
private long machineId; // corresponds to PK type of Machine
private long index;
// ...
}
}
机器:
@Entity
public class Machine {
@Id
private long id;
@OneToMany(mappedBy = "machine")
private List<MachineLine> lines;
// ...
}
[2.4.1节的JPA 2.2 spec中讨论了导出的身份(带有示例)]