【发布时间】:2016-12-15 17:50:55
【问题描述】:
我有下表:
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])
有没有在不创建两个表的情况下使用 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)
提前致谢。
【问题讨论】:
-
您的问题是您将实体
Stack定义为使用与Slot相同的表(出于某种原因)。其中一个的 PK 为 (byte,Stack),另一个的 PK 为 (int,int)。完全不兼容 -
是的,我知道。 Stack 是展示 Slots 的不同方式(按坐标分组)。我可以实现两个单独的表,但如果 Stacks 只是插槽组,它就没有意义。这就是为什么我问是否有任何方法可以用一张表来实现。
-
使用 RDBMS 视图可能是我考虑的唯一方法
-
哈。关键是,视图使您只能选择。我也想保留数据。 ://
-
@MapsId 注释呢?在这里有用吗?
标签: java hibernate jpa jakarta-ee jpa-2.0