我有
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
public Linf getLinf() {
return linf;
}
和
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, targetEntity = MessageEntry.class)
public Set<MessageEntry> getMessageEntries() {
return messageEntries;
}
我需要从数据库中删除单个messageEntry。如果我说sess.delete(messageEntry),那么我在Linf.messageEntries集合中得到索引异常。无状态会话无法加载集合,所以我有 手动加载Linf.messageEntries的元素,然后删除其中一个元素:
List linfs = sess.createQuery(
"SELECT l FROM Linf l " +
"JOIN l.messageEntries e WHERE e=:e")
.setParameter("e", messageEntry).list();
if (linfs.size()>1) throw new RuntimeException();
Linf linf = (Linf) linfs.get(0);
List<MessageEntry> curEntries =
sess.createQuery(
"SELECT e FROM Linf l " +
"JOIN l.messageEntries e WHERE l=:l")
.setParameter("l", linf).list();
for (int i = 0; i < curEntries.size(); i++) {
if (curEntries.get(i).getId().equals(messageEntry.getId())) {
curEntries.remove(i);
break;
}
}
Set<MessageEntry> cur = new HashSet<MessageEntry>();
cur.addAll(curEntries);
linf.setMessageEntries(cur);
messageEntry.setLinf(null);
sess.update(messageEntry);
sess.update(linf);
sess.delete(messageEntry);
我得到ConstraintViolationException:无法删除或更新父行:外键约束失败(db
。linf_messageentry
,CONSTRAINT FK5039A8B5E770809A
FOREIGN KEY(messageEntries_id
)REFERENCES { {1}}(messageentry
))。我该如何执行此任务?谢谢。
答案 0 :(得分:1)
您的映射是错误的。使用MessageEntry中的外键,不是使用双向一对多关联,而是使用连接表(linf_messageentry
)进行OneToMany关联,使用外键进行另一个不同的ManyToOne关联。
必须使用mappedBy
属性将一边标记为多边的反面:
// This is the owner side of the association, because it doesn't have
// the mappedBy attribute.
// it uses a join column by default
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
public Linf getLinf() {
return linf;
}
和
// This is the inverse side, because it has the mappedBy attribute
// since it's mappedBy linf, hibernate uses the same mapping as the one
// described on the linf property: a join column
@OneToMany(mappedBy = "linf", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
public Set<MessageEntry> getMessageEntries() {
return messageEntries;
}
另外,请注意:
targetEntity
属性是完全冗余的:Hibernate从集合的类型中知道目标实体:Set<MessageEntry>