2011-02-05 14 views
6

私はHibernateへのJPAインターフェイスを使用しています。データベースからエンティティを読み込んで削除(削除)する簡単なコードを記述しました。エンティティの挿入と更新のためのすべてのマージコールは完全に動作していますが、エンティティを削除しようとすると、Hibernateはデータベースからそのエンティティを削除せず、例外もスローされません。JPA/Hibernate removeエンティティが機能しない

プライマリ方法:(すべてのDAOクラスによって継承されます)

/** 
* 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クラス:

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

することでこれを解決しました* DaoMgr * s)。それは不必要に問題の理解を複雑にするので上記のあなたの例でそれを訂正するとよいでしょう。 –

答えて

3

EventInviteがトランザクションの境界を超えているので混乱しますか? 1つのトランザクションでエンティティをロードし、別のトランザクションでエンティティを削除します。

代わりに、1つの論理操作であるため、招待を受け入れるための完全なビジネスロジックを含む新しい@Transactionalメソッドを作成します。そうすることで、SMSまたは電子メールで招待を受け入れることができるようにするために、プレゼンテーションレイヤーをモデルから分離することもできます。

+0

あなたは天才です。完璧に働いた、Davidに感謝! – Templar

0

こんにちは あなたは私はあなたが削除すると、何らかの形でセッションまたはトランザクションはそうではないでしょうが、フラッシュ休止状態に閉じられていないということである疑いが何

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

を設定することにより実行されたSQLのを見しようとすることができます休止状態との結果であろうデータベースには表示されません。

+1

私はJDBCクエリのログを有効にしており、Hibernateはそのレコードを削除しようとしていません。また、削除呼び出しが永続化される直前のeventMemberDAO.storeコールは、トランザクション上の問題ではないと私は考えています。 – Templar

3

私は同様の問題を抱えていましたが、カテゴリの一部である値を記述するクラスがありました。したがって、価値クラスには、そのクラスの一部であるカテゴリへの参照があります。

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

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

    @ManyToOne 
    private Category category; 
} 

私は手動で私はCategoryValueオブジェクトを削除することができたの前にゼロにするために、カテゴリフィールドを設定する必要がありましたHibernateはこのように動作し、なぜ、私は本当に知りません。

+0

これは欠けていたリンクです:-) –

1

私は同じ問題を抱えていました。 私のエンティティはカードです(下記参照)。そして私は データベースでのヌルチェックではないので、アカウントとクライアントにnullを設定できませんでした。

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

私はそれを削除しようとしたときにも、削除についてのSQLリクエストは表示されませんでした。

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

は、だから私はあなたのコードは、あなたの `AbstractJpaDao`と` eventMemberDAO`は実際にはありません* DAOの* sではなく* EntityManagerのラッパー* S(またはそうあなたの場合ので、混乱して、注釈

@ManyToOne(cascade=CascadeType.MERGE) 
@JoinColumn(name="idAcc") 
private Account account; 
@ManyToOne(cascade=CascadeType.MERGE) 
@JoinColumn(name="idCl") 
private Client client; 
関連する問題