【发布时间】:2018-01-14 20:53:42
【问题描述】:
我正在使用 Spring Boot 和 Hibernate 编写一个 API,其中我的持久实体对象也用作发送到客户端和从客户端发送的 DTO。这是我使用的典型实体的简化版本:
@Entity
@Table(name = "STUDENT")
public class Student {
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@ElementCollection
@CollectionTable(name = "GROUP_STUDENT",
joinColumns = @JoinColumn(name = "GROUP_ID"))
@Column(name="STUDENT_ID")
private Set<Long> groupIds;
@JsonIgnore
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name="GROUP_STUDENT",
joinColumns = @JoinColumn(name="GROUP_ID"),
inverseJoinColumns = @JoinColumn(name="STUDENT_ID")
)
private Set<Group> groups = new HashSet<>();
// getters and setters
}
这是相关的类:
@Entity
@Table(name = "GROUP")
public class Group {
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@JsonIgnore
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "groups")
private Set<Student> students = new HashSet<>();
// getters and setters
}
如您所见,Student 和 Group 之间存在 @ManyToMany 关联。
由于我将此类对象发送给客户端,因此我选择仅发送关联的 id 而不是关联本身。我已经使用this answer 解决了这个问题,它按预期工作。
问题是这样的。当 hibernate 尝试持久化一个Student 对象时,它会按预期插入groups,但它也会尝试将groupIds 插入到映射表GROUP_STUDENT 中。由于映射表复合 id 的唯一约束,这当然会失败。并且不可能将groupIds 标记为insertable = false,因为它是@ElementCollection。而且我认为我不能使用@Formula,因为我需要Set,而不是减少值。
这当然可以通过在保存或持久化这样的实体之前始终清空groupIds 或groups 来解决,但这是非常冒险且容易忘记的。
所以我想要的基本上是Student 类中的只读groupIds,它从GROUP_STUDENT 映射表加载数据。这可能吗?我很感谢您提出的任何建议,如果问题看起来不清楚,我很乐意详细说明。
【问题讨论】:
标签: java spring hibernate jpa many-to-many