[英]How can I delete element from collection using stateless session? (ConstraintViolationException)
I have 我有
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
public Linf getLinf() {
return linf;
}
and 和
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, targetEntity = MessageEntry.class)
public Set<MessageEntry> getMessageEntries() {
return messageEntries;
}
I need to remove single messageEntry from database. 我需要从数据库中删除单个messageEntry。 If I say sess.delete(messageEntry), then I get index exception since its in Linf.messageEntries collection.
如果我说sess.delete(messageEntry),那么我会从Linf.messageEntries集合中获取索引异常。 Stateless session can't load collection, so I have to load elements of Linf.messageEntries mannually and then remove one of them:
无状态会话无法加载集合,因此我必须手动加载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);
I get ConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails ( db
. linf_messageentry
, CONSTRAINT FK5039A8B5E770809A
FOREIGN KEY ( messageEntries_id
) REFERENCES messageentry
( id
)). 我得到ConstraintViolationException:不能删除或更新父行,外键约束失败(
db
。 linf_messageentry
,约束FK5039A8B5E770809A
外键( messageEntries_id
)参考messageentry
( id
))。 How can I perform this task? 如何执行此任务? Thank you.
谢谢。
Your mapping is wrong. 您的映射错误。 Instead of having a bidirectional one-to-many association, using a foreign key in MessageEntry, you have a OneToMany association using a join table (
linf_messageentry
), and another, distinct, ManyToOne association using a foreign key. 与在MessageEntry中使用外键而不是双向的一对多关联相比,您具有使用
linf_messageentry
表( linf_messageentry
)的OneToMany关联,以及使用外键的另一个独特的ManyToOne关联。
The one side must be marked as the inverse of the many side, using the mappedBy
attribute: 必须使用
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;
}
and 和
// 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;
}
Also, note that: 另外,请注意:
targetEntity
attribute is completly redundant: Hibernate knows the target entity from the type of the collection: Set<MessageEntry>
targetEntity
属性是完全冗余的:Hibernate从集合的类型中知道目标实体: Set<MessageEntry>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.