@Entity
public class Report extends Model {
public Date date;
public double availability;
@ElementCollection
@Cascade(value={CascadeType.ALL})
public Map<FaultCategory, Integer> categories;
}
在我的一项工作中,我有以下代码:
int n = MonthlyReport.delete("date = ?", date);
这总是无法删除具有以下错误的实体:
DELETE语句与REFERENCE约束“FK966F0D9A66DB1E54”冲突。冲突发生在数据库“TFADB”,表“dbo.MonthlyReport_categories”,列'MonthlyReport_id'。
如何指定映射,以便在删除报告时删除categories集合中的元素?
答案 0 :(得分:27)
级联删除(以及一般的级联操作)仅在通过EntityManager
进行操作时有效。不是通过JP QL / HQL查询以批量删除方式完成删除。当通过查询执行删除时,您无法指定将删除链接到ElementCollection
中的元素的映射。
ElementCollection
注释没有级联属性,因为操作总是级联的。当您通过EntityManager.remove()
删除实体时,操作会级联到ElementCollection
。
您必须获取要删除的所有MonthlyReport
个实体,并为每个实体调用EntityManager.remove
。在Play框架中看起来不是这样,你也可以在实体中调用delete-method。
答案 1 :(得分:2)
J.T。提供的答案是正确的,但对于我和他/她的评论中提到的sebge2来说并不完整。
@ElementCollection
和@OnDelete
的组合还需要@JoinColumn()
。
后续示例:
@Entity
public class Report extends Model {
@Id
@Column(name = "report_id", columnDefinition = "BINARY(16)")
public UUID id; // Added for the sake of this entity having a primary key
public Date date;
public double availability;
@ElementCollection
@CollectionTable(name = "report_category", joinColumns = @JoinColumn(name = "report_id")) // choose the name of the DB table storing the Map<>
@MapKeyColumn(name = "fault_category_key") // choose the name of the DB column used to store the Map<> key
@Column(name = "fault_category_value") // choose the name of the DB column used to store the Map<> value
@JoinColumn(name = "report_id") // name of the @Id column of this entity
@OnDelete(action = OnDeleteAction.CASCADE)
@Cascade(value={CascadeType.ALL})
public Map<FaultCategory, Integer> categories;
}
此设置将创建一个名为report
的表和另一个具有三列的表report_category
:report_id, fault_category_key, fault_category_value
。 report_category.report_id
和report.report_id
之间的外键约束为ON DELETE CASCADE
。我使用Map
答案 2 :(得分:0)
我遇到了同样的问题,这是我的代码示例。
@ElementCollection
@CollectionTable(name = "table_tag", joinColumns=@JoinColumn(name = "data_id"))
@MapKeyColumn(name = "name")
@Column(name = "content")
private Map<String, String> tags
最后,经过大量尝试,我只是将table_tag.data_id的外键约束添加到父表的主键中。注意,您应该将ON DELETE CASCADE设置为约束。 您可以通过任何方式删除父实体,子元素集合也将被删除。
答案 3 :(得分:-1)
我们找到了魔术票!将 OnDelete(action = OnDeleteAction.CASCADE)添加到ElementCollection。这使我们可以从SQL(在entityManager外部)删除该项目。