JPA/Hibernate удалить сущность не работает
Я использую интерфейс JPA для Hibernate, и я написал простой код для загрузки объекта из базы данных, а затем удалить (удалить) его. Все мои вызовы слияния для вставки и обновления сущностей работают отлично, но когда я пытаюсь удалить сущность, Hibernate не удаляет ее из базы данных, и исключение не выдается. Я включил соответствующий код ниже:
Основной метод:
/**
* 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;
}
}
Любые идеи о том, что проблема может быть или как ее отладить?
4 ответа
Это путается, потому что EventInvite
пересекает границы транзакций? Вы загружаете сущность в одну транзакцию и удаляете ее в другой.
Вместо этого создайте новый @Transactional
метод, который содержит полную бизнес-логику для принятия приглашения, так как это одна логическая операция. Это также отделит презентационный слой от модели, когда вы хотите разрешить прием приглашений по SMS или электронной почте.
У меня была похожая проблема, у меня был класс, который описывает значение, которое является частью категории. Таким образом, класс значения имеет ссылку на категорию, частью которой он является.
@Entity
public class CategoryValue extends LouhinObject implements Serializable, Idable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
private Category category;
}
Мне пришлось вручную установить в поле категории значение null, прежде чем я смог удалить объект CategoryValue, я действительно не знаю, почему Hibernate работает таким образом.
У меня такая же проблема. Моя сущность - это Карта (см. Ниже). И я не мог установить ноль для учетной записи и клиента, потому что у меня есть проверки не-нуль в базе данных.
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();
Так что я решил это аннотациями
@ManyToOne(cascade=CascadeType.MERGE)
@JoinColumn(name="idAcc")
private Account account;
@ManyToOne(cascade=CascadeType.MERGE)
@JoinColumn(name="idCl")
private Client client;
Привет Для Hibernate вы можете попытаться увидеть выполненные sql, установив
<property name="hibernate.show.sql" value="true"></property>
Я подозреваю, что при удалении сеанс или транзакция каким-либо образом не закрываются, поэтому hibernate не сбрасывается и результаты не отображаются в базе данных.