java JPA/Hibernate 删除实体不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4909401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA/Hibernate remove entity not working
提问by Templar
I'm using a JPA interface to Hibernate, and I've written some simple code to load an entity from the database and then remove (delete) it. All of my merge calls to insert and update entities are working perfectly, but when I try to remove an entity, Hibernate doesn't delete it from the database, and no exception is thrown. I've included the relevant code below:
我正在使用 Hibernate 的 JPA 接口,并且我编写了一些简单的代码来从数据库加载一个实体,然后删除(删除)它。我对插入和更新实体的所有合并调用都运行良好,但是当我尝试删除一个实体时,Hibernate 不会将它从数据库中删除,也不会抛出任何异常。我在下面包含了相关代码:
Primary method:
主要方法:
/**
* Accept an invite that was sent to you.
*
* @param inviteId
* @return XML model of the EventMember.
*/
@RequestMapping(value="/invites/accept.rest")
public ModelAndView acceptInvite(@RequestParam final long inviteId) {
final EventInvite invite = eventInviteDAO.find(EventInvite.class, eventInviteId);
EventMember eventMember = new EventMember();
eventMember.setEvent(invite.getEvent());
eventMember.setUser(invite.getUser());
eventMember = eventMemberDAO.store(eventMember);
eventInviteDAO.remove(invite);
return getXMLModelAndView("eventMember", eventMember);
}
AbstractJpaDao class (inherited by all DAO classes):
AbstractJpaDao 类(由所有 DAO 类继承):
public abstract class AbstractJpaDao<T> implements JpaDao<T> {
abstract public EntityManager getEntityManager();
public <T> T find(Class<T> entityClass, Object primaryKey) {
return getEntityManager().find(entityClass, primaryKey);
}
@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
public T store(final T objectToPersist) {
T result = getEntityManager().merge(objectToPersist);
return result;
}
@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
public void remove(final T objectToDelete) {
getEntityManager().remove(objectToDelete);
}
}
EventInvite domain class:
EventInvite 域类:
@Entity
@Table(name = "TEventInvite")
public class EventInvite implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name = "EventInviteID", nullable = false)
@Basic(fetch = FetchType.EAGER)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long eventInviteId;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumns( { @JoinColumn(name = "EventID", referencedColumnName = "EventID", nullable = false) })
private Event event;
@Column(name = "Email")
@Basic(fetch = FetchType.EAGER)
private String email;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "CreateDate", nullable = false)
@Basic(fetch = FetchType.EAGER)
private Calendar createDate;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumns( { @JoinColumn(name = "UserID", referencedColumnName = "UserID") })
private User user;
public void setEventInviteId(long eventInviteId) {
this.eventInviteId = eventInviteId;
}
public long getEventInviteId() {
return this.eventInviteId;
}
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return this.email;
}
public void setCreateDate(Calendar createDate) {
this.createDate = createDate;
}
public Calendar getCreateDate() {
return this.createDate;
}
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((createDate == null) ? 0 : createDate.hashCode());
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result + ((event == null) ? 0 : event.hashCode());
result = prime * result + ((user == null) ? 0 : user.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EventInvite other = (EventInvite) obj;
if (createDate == null) {
if (other.createDate != null)
return false;
} else if (!createDate.equals(other.createDate))
return false;
if (email == null) {
if (other.email != null)
return false;
} else if (!email.equals(other.email))
return false;
if (event == null) {
if (other.event != null)
return false;
} else if (!event.equals(other.event))
return false;
if (user == null) {
if (other.user != null)
return false;
} else if (!user.equals(other.user))
return false;
return true;
}
}
Any ideas about what the problem might be or how to debug it?
关于问题可能是什么或如何调试它的任何想法?
采纳答案by David Harkness
Is it getting confused because the EventInvite
crosses transaction boundaries? You load the entity in one transaction and delete it in another.
是否因为EventInvite
跨事务边界而感到困惑?您在一个事务中加载实体并在另一个事务中删除它。
Instead, create a new @Transactional
method that contains the complete business logic for accepting an invite as it is a single logical operation. Doing so will also separate the presentation layer from the model for when you want to enable accepting invitations via SMS or email.
相反,创建一个@Transactional
包含接受邀请的完整业务逻辑的新方法,因为它是单个逻辑操作。当您希望通过 SMS 或电子邮件接受邀请时,这样做还会将表示层与模型分开。
回答by user344146
I had a similar problem, I had a class which describes a value which is a part of a category. So the value class has a reference to the category that it is a part of.
我有一个类似的问题,我有一个类描述了一个属于类别的值。因此,值类引用了它所属的类别。
@Entity
public class CategoryValue extends LouhinObject implements Serializable, Idable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
private Category category;
}
I had to manually set the category field to null before I was able to remove the CategoryValue object, I don't really know why Hibernate works this way.
在我能够删除 CategoryValue 对象之前,我必须手动将 category 字段设置为 null,我真的不知道为什么 Hibernate 以这种方式工作。
回答by Foontik
I had the same problem. My entity is Card (see below). And I couldn't set null to an account and a client, because I have not-null checks in database.
我有同样的问题。我的实体是 Card(见下文)。而且我无法将帐户和客户端设置为空,因为我在数据库中进行了非空检查。
public class Card implements Serializable {
@ManyToOne
@JoinColumn(name="idAcc")
private Account account;
@ManyToOne
@JoinColumn(name="idCl")
private Client client;
And when I tryed to delete it I even didn't see sql-request about deleting.
当我尝试删除它时,我什至没有看到关于删除的 sql-request。
em = getEntityManager();
em.getTransaction().begin();
mergedCard = em.merge(card);
em.remove(mergedCard);
em.getTransaction().commit();
So I resolved this by annotations
所以我通过注释解决了这个问题
@ManyToOne(cascade=CascadeType.MERGE)
@JoinColumn(name="idAcc")
private Account account;
@ManyToOne(cascade=CascadeType.MERGE)
@JoinColumn(name="idCl")
private Client client;
回答by Cris
Hi For hibernate you can try to see executed sql's by setting
嗨,对于休眠,您可以尝试通过设置查看已执行的 sql
<property name="hibernate.show.sql" value="true"></property>
What i suspect is that when you delete ,somehow the session or transaction is not closed so hibernate will not flush and the results will not be seen in database.
我怀疑的是,当您删除时,会话或事务以某种方式没有关闭,因此休眠不会刷新并且结果不会在数据库中看到。