两个对象与一个 table 持久化(第一个由第二个聚合)

Two objects persisted with one table (first is aggregated by second)

我关注table:

  Column   |  Type   | Modifiers 
-----------+---------+-----------
 palett_id | integer | not null
 x         | integer | not null
 y         | integer | not null
 sequence  | integer | not null
Indexes:
    "slots_palett_id_key" UNIQUE CONSTRAINT, btree (palett_id)
    "slots_x_y_sequence_key" UNIQUE CONSTRAINT, btree (x, y, sequence)
Foreign-key constraints:
    "slots_palett_id_fkey" FOREIGN KEY (palett_id) REFERENCES palettes(palett_id)

现在我想从中创建两个对象:

插槽:

@Entity
@Table(name = Slot.TABLE)
public class Slot implements Serializable {
    public static final String TABLE = "slots";
    public static final String COORDINATE_X = "x";
    public static final String COORDINATE_Y = "y";
    public static final String SEQUENCE = "sequence";

    @OneToOne
    @JoinColumn(name = Palett.ID)
    private Palett palett;

    @Id
    @Column(name = Slot.SEQUENCE)
    private byte position;

    @Id
    @ManyToOne
    @JoinColumns({@JoinColumn(name = Slot.COORDINATE_X), @JoinColumn(name = Slot.COORDINATE_Y)})
    @JsonIgnore
    private Stack stack;
}

和堆栈,由插槽组成:

@Entity
@Table(name = Slot.TABLE)
public class Stack {

    @EmbeddedId
    private Coordinates coordinates;

    @OneToMany(mappedBy = "stack", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @OrderBy(value = Slot.SEQUENCE + " ASC")
    private List<Slot> slots;

    public Stack() {}

    public Stack(Coordinates coordinates) {
        this.coordinates = coordinates;
        this.slots = new LinkedList<>();
    }

    public void addSlot(Slot s) {
        this.slots.add(s);
        s.setStack(this);
        s.setPosition((byte) this.slots.size());
    }
}

我也得到了对象坐标:

@Embeddable
public class Coordinates implements Serializable {

    @Column(name = Slot.COORDINATE_X)
    private int x;

    @Column(name = Slot.COORDINATE_Y)
    private int y;

    public Coordinates(int x, int y) {
        this.x=x;
        this.y=y;
    }

    public Coordinates(){}
}

我的问题是,对象槽具有三字段键 (x,y,sequence),而我想从具有两字段键 (x,y) 的堆栈中引用它。所以我得到了以下错误:

Caused by: org.hibernate.MappingException: Foreign key (FKjcydeens7h0219w5bwf075hpc:slots [x,y])) must have same number of columns as the referenced primary key (slots [x,y,sequence])

有没有办法在不创建两个 table 的情况下使用 JPA 实现它?:

 stacks (id, x, y)
 slots(stack_id, sequence, palett_id)

当我从 private byte position 中删除 @Id 时,代码编译正确,但结果不正确(如果一个堆栈中有两个槽,我得到 2 个包含重复元素的元素列表 - 第一个),即:

palett_id, x, y, sequence
    1      1  1     1
    2      1  1     2

结果我得到:

Stack -> Slot(id = 1), Slot(id=1)

提前致谢。

我按照@neil-stockton 的建议创建了以下视图:

create or replace view stacks as select distinct x,y from slots;