带有复合键的@OneToOne 实体上的JPA @Id

JPA @Id on @OneToOne Entity with a Composite Key

我有一个 @Entity class,在同一字段上有一个 @Id 注释和一个 @OneToOne 注释。通常这不会有问题,但带有这些注释的字段的实体 class 使用复合键。这导致的并发症比我预期的要多。

这是造成问题的实体 class:

@Entity
public class ReportDetails implements Serializable {

    @Id
    @OneToOne
    private MachineLine machineLine;
}

这里是 MachineLine 实体 class,在 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;
    }
}

为了保存 space.

,我从这些 class 定义中省略了任何额外的字段以及 getter 和 setter

当我尝试 运行 我的应用程序时,出现以下异常:

java.lang.IllegalArgumentException: This class [class ReportDetails] does not define an IdClass

当我在 ReportDetails 上放置 @IdClass 注释时,它需要定义我在 @IdClass 中定义的任何 class 的各个字段,就像在 [=15= 中一样].但是,我试图避免这样做,而是希望在从数据库中检索到 ReportDetails 实体时返回整个 MachineLine 实体。

有没有办法将 MachineLine 作为 ReportDetails 的 ID 字段,而不必在 ReportDetails 中定义额外的字段?

这就是 JPA 所说的 "derived identity"。您可以尝试这样的操作:

报告详情:

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

    // ...
}

机器生产线:

@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 中讨论(带有示例)。