JPA2.0:删除OneToMany关系中的实体
如何删除 OneToMany 关系中的实体。
@Entity
@NamedQueries({
@NamedQuery(name="User.findByUserNamePassword",
query="select c from User c where c.userName = :userName AND c.password = :password")
})
@Table(name="\"USER\"")
public class User implements Serializable {
@OneToMany(mappedBy="user", cascade=CascadeType.ALL, orphanRemove=true)
private List<Profession> professions;
public List<Profession> getProfessions() {
return professions;
}
public void setProfessions(List<Profession> professions) {
this.professions = professions;
}
public void addProfession(Profession profession){
if(this.professions == null){
this.professions = new ArrayList<Profession>();
}
this.professions.add(profession);
profession.setUser(this);
}
public void removeProfession(Profession profession){
if(this.professions != null){
professions.remove(profession);
profession.setUser(null);
}
}
}
内部专业实体
@Entity
public class Profession implements Serializable {
@ManyToOne
@JoinColumn(name="UserId", nullable=false)
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
然后在我的 EJB 中,我
@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class ScholarEJB{
/**
* Add a profession to a target user
* @param user
* @param profession
*/
public void addProfession(User user, Profession profession){
//Put the user in a managed state. It is important to do this before
//adding a new profession onto user
user = find(User.class, user.getId());
user.addProfession(profession);
this.create(user); //This is persist action
}
public void removeProfession(User user, Profession profession){
//Put the user in a managed state. It is important to do this before
//adding a new profession onto user
user = find(User.class, user.getId());
user.remove(user);
this.update(user); //merge action
//this.create(user) //also try this as well, but it does not work
}
}
现在 addProfession
工作得很好,但是 removeProfession
不起作用。不知道为什么?请帮忙。我需要清除缓存吗?
How do I delete an entity in a OneToMany relationship.
@Entity
@NamedQueries({
@NamedQuery(name="User.findByUserNamePassword",
query="select c from User c where c.userName = :userName AND c.password = :password")
})
@Table(name="\"USER\"")
public class User implements Serializable {
@OneToMany(mappedBy="user", cascade=CascadeType.ALL, orphanRemove=true)
private List<Profession> professions;
public List<Profession> getProfessions() {
return professions;
}
public void setProfessions(List<Profession> professions) {
this.professions = professions;
}
public void addProfession(Profession profession){
if(this.professions == null){
this.professions = new ArrayList<Profession>();
}
this.professions.add(profession);
profession.setUser(this);
}
public void removeProfession(Profession profession){
if(this.professions != null){
professions.remove(profession);
profession.setUser(null);
}
}
}
Inside Profession Entity
@Entity
public class Profession implements Serializable {
@ManyToOne
@JoinColumn(name="UserId", nullable=false)
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
Then inside my EJB I have this
@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class ScholarEJB{
/**
* Add a profession to a target user
* @param user
* @param profession
*/
public void addProfession(User user, Profession profession){
//Put the user in a managed state. It is important to do this before
//adding a new profession onto user
user = find(User.class, user.getId());
user.addProfession(profession);
this.create(user); //This is persist action
}
public void removeProfession(User user, Profession profession){
//Put the user in a managed state. It is important to do this before
//adding a new profession onto user
user = find(User.class, user.getId());
user.remove(user);
this.update(user); //merge action
//this.create(user) //also try this as well, but it does not work
}
}
Now addProfession
work beautifully, but removeProfession
does not work. Not sure why? Help please. Do I need to evict caches?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是我原来问题的解决方案,但是,我不知道这是否是最好的
我的 EJB bean
现在在我的托管 Bean 中,我这样做
This is the solution to my original question, however, I do not know if this is the best
My EJB bean
Now in my Managed Bean, I do this
如果职业只是此关系的一部分,那么您可以保证当职业从用户集中删除时,通过在关系的 OneToMany 端打开 orphanRemoval,它也将从数据库中删除。
这就是 JPA 2.0 规范的规定
JPA 2.0 规范规定
If professions are only part of this relationship, then you can guarantee that when a profession is removed from the User's set it will also be removed from the database by turning on orphanRemoval on the OneToMany side of the relationship.
This is what the JPA 2.0 specification states
The JPA 2.0 specification states that
我对正在发生的事情的猜测是,您的用户与专业具有一对多关系,并且您的用户对象具有该专业。当您删除职业时,用户仍然拥有参考。因为映射是级联持久化的,所以它重新持久化了职业。
您需要确保在删除该职业之前将该职业从用户的职业中删除。
如果您使用 EclipseLink,则有一个属性也可能有所帮助,但修复代码以正确维护模型是最好的解决方案。您还可以删除级联持久化。
“eclipselink.persistence-context.persist-on-commit”=“false”
或者,
“eclipselink.persistence-context.commit-without-persist-rules”=“true”
My guess as to what is occurring is that your User has a OneToMany relationship to Profession and you user object has the profession. When you delete the Profession the user still has the reference. Because the mapping is cascade persist, it re persists the Profession.
You need to ensure that you remove the profession from the user's professions before deleting it.
If you are using EclipseLink there is a property that may also help, but fixing your code to maintain your model correctly is the best solution. You could also remove the cascade persist.
"eclipselink.persistence-context.persist-on-commit"="false"
or,
"eclipselink.persistence-context.commit-without-persist-rules"="true"
我刚刚在 OneToMany 关系中添加了
orphanRemoval = true
并且解决了它。类
SolicitudRetorno
:类
RetornoMenor
:I just added
orphanRemoval = true
in the OneToMany relationship and I resolved it.Class
SolicitudRetorno
:Class
RetornoMenor
:您可以尝试清除专业中的用户字段:
为了安全起见,我还会检查传入的专业的当前用户是否等于
this
,以防万一有人传入属于另一个用户的专业。You might try clearing the user field in profession:
To be on the safe side, I would also check that the passed in profession's current user equals
this
, just in case someone passes in a profession belonging to another user.