2011-02-05 172 views
6

我正在使用JPA接口来Hibernate,我写了一些简单的代码来从数据库中加载实体,然后删除(删除)它。我所有的插入和更新实体的合并调用都可以正常工作,但是当我尝试删除一个实体时,Hibernate不会从数据库中删除它,也不会引发异常。我已经包括以下相关代码:JPA /休眠删除实体不工作

主要方法:

/** 
* 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类(由所有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域类:

@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; 
    } 

} 

关于问题可能是什么或如何调试的任何想法?

+0

你的代码是因为你的`AbstractJpaDao`混乱和`eventMemberDAO`实际上不是* DAO * S *,但EntityManager的包装* S(或者,如果你这么将* DaoMgr * s)。如果你在上面的例子中纠正它会很好,因为它不必要地使问题的理解复杂化。 – 2016-11-18 08:38:29

回答

3

难道由于EventInvite跨越交易界限而感到困惑吗?您将实体加载到一个事务中,并在另一个事务中删除它。

取而代之,请创建一个新的@Transactional方法,该方法包含接受邀请的完整业务逻辑,因为它是单个逻辑操作。这样做也会将表示层与模型分开,以便您希望通过SMS或电子邮件启用接受邀请。

+0

你是个天才。工作得很好,谢谢大卫! – Templar 2011-02-05 22:54:38

0

嗨 对Hibernate,你可以尝试通过设置

<property name="hibernate.show.sql" value="true"></property> 

我怀疑那是什么,当你删除,不知何故会话或交易没有关闭,因为Hibernate不会冲洗看执行的SQL的,其结果将在数据库中不可见。

+1

我打开了JDBC查询日志记录,Hibernate甚至没有尝试删除记录。此外,在移除调用之前立即调用eventMemberDAO.store调用,所以我认为这不是一个事务性问题。 – Templar 2011-02-05 21:42:29

3

我有一个类似的问题,我有一个类,它描述了一个类别的一部分的值。所以价值类有一个参考,它是它的一部分。

@Entity 
public class CategoryValue extends LouhinObject implements Serializable, Idable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @ManyToOne 
    private Category category; 
} 

我不得不手动设置类别字段设置为null,我能够删除的categoryValue对象,我真的不知道为什么Hibernate的这种方式工作之前。

+0

这是我需要的缺失链接:-) – 2012-09-14 14:18:22

1

我有同样的问题。 我的实体是卡片(见下文)。我无法将空值设置为一个帐户和一个客户端,因为我在数据库中有 非空检查。

public class Card implements Serializable { 
    @ManyToOne 
    @JoinColumn(name="idAcc") 
    private Account account; 
    @ManyToOne 
    @JoinColumn(name="idCl") 
    private Client client; 

而当我试图删除它,我甚至没有看到有关删除的sql-request。

em = getEntityManager(); 
    em.getTransaction().begin(); 
    mergedCard = em.merge(card); 
    em.remove(mergedCard); 
    em.getTransaction().commit(); 

所以我通过注释解决了这个

@ManyToOne(cascade=CascadeType.MERGE) 
@JoinColumn(name="idAcc") 
private Account account; 
@ManyToOne(cascade=CascadeType.MERGE) 
@JoinColumn(name="idCl") 
private Client client;