2011-02-05 22 views
6

Estoy usando una interfaz JPA para Hibernate, y he escrito un código simple para cargar una entidad de la base de datos y luego eliminarla (eliminarla). Todas mis llamadas de combinación para insertar y actualizar entidades funcionan perfectamente, pero cuando intento eliminar una entidad, Hibernate no la elimina de la base de datos y no se lanza ninguna excepción. He incluido el código correspondiente a continuación:entidad de eliminación de JPA/Hibernate no funciona

método primario:

/** 
* 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); 
} 

clase AbstractJpaDao (heredado por todas las clases 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); 
    } 
} 

clase de dominio 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; 
    } 

} 

¿Alguna idea sobre cuál podría ser el problema o cómo depurarlo?

+0

su código es confuso ya que su '' AbstractJpaDao' y eventMemberDAO' en realidad no son DAO * * * s, pero envoltorio EntityManager * s (o, si así lo * DaoMgr * s). sería bueno si lo corrige en su ejemplo anterior, ya que complica innecesariamente la comprensión del problema. –

Respuesta

3

¿Se está confundiendo porque el EventInvite cruza los límites de las transacciones? Usted carga la entidad en una transacción y la elimina en otra.

En su lugar, cree un nuevo método @Transactional que contenga la lógica comercial completa para aceptar una invitación, ya que es una operación lógica única. Al hacerlo, también se separará la capa de presentación del modelo para cuando quiera permitir la aceptación de invitaciones por SMS o correo electrónico.

+0

Eres un genio. Funcionó perfectamente, gracias David! – Templar

0

Hola Para hibernar se puede tratar de ver ejecutados de SQL mediante el establecimiento de

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

lo que sospecho es que cuando se elimina, de alguna manera la sesión o transacción no está cerrado, así hibernación no descarga y los resultados no ser visto en la base de datos.

+1

He activado el registro de consultas JDBC e Hibernate ni siquiera está intentando eliminar el registro. Además, la llamada eventMemberDAO.store inmediatamente antes de que se elimine la llamada de eliminación, por lo que no creo que sea un problema de transacción. – Templar

3

Tuve un problema similar, tuve una clase que describe un valor que es parte de una categoría. Entonces, la clase de valor tiene una referencia a la categoría de la que forma parte.

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

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

    @ManyToOne 
    private Category category; 
} 

tuve que configurar manualmente el campo de categoría en null antes de que yo era capaz de extraer el objeto CategoryValue, no se sabe muy bien por qué Hibernate funciona de esta manera.

+0

Ese era el eslabón perdido que necesitaba :-) –

1

Tuve el mismo problema. Mi entidad es Tarjeta (ver a continuación). Y no pude establecer el nulo en una cuenta y un cliente, porque tengo comprobaciones no nulas en la base de datos.

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

Y cuando intenté eliminarlo, incluso no vi sql-request sobre la eliminación.

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

Así que resolvieron mediante anotaciones

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