У меня есть два объекта: событие и пользователь. Оба имеют ссылки друг на друга:Hibernate - удалить запрос из @ManyToMany
@Entity
@Table(name = "Event")
public class Event implements Serializable {
//some fields
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "Event_User",
joinColumns = @JoinColumn(name = "event_id", nullable = false, updatable = false),
inverseJoinColumns = @JoinColumn(name = "user_id", nullable = false, updatable = false))
List<User> attendingUsers = new ArrayList<User>();
//Getters and Setters
}
@Entity
@Table(name = "User")
public class User implements Serializable {
//Attributes
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "attendingUsers")
private List<Event> attendingEvents = new ArrayList<Event>();
//Getters and Setters
}
Хорошо, теперь у меня есть ситуации, когда я хочу, чтобы пользователи смогли Unattend события. До сих пор я пробовал несколько вещей, но похоже, что только запрос будет работать. Причина, по которой я хочу использовать запрос, заключается в следующем: я не могу использовать Hibernate.initialize(event.getAttendingUsers())
, и поэтому event.getAttendingUsers().clean()
этого не сделает.
Мой запрос выглядит это так далеко:
@Transactional(propagation= Propagation.REQUIRED, readOnly=false)
@Service("eventService")
public class EventService implements IEventService {
public void unattend(Event e, User u){
Query query = sessionFactory.getCurrentSession().createQuery(
"SELECT u FROM User AS u LEFT JOIN FETCH u.attendingEvents AS ae WHERE ae.id = :id");
query.setParameter("id", e.getId());
List<User> attendingUsers = (List<User>)query.list();
if(attendingUsers.contains(u)){
Query delete = sessionFactory.getCurrentSession().createQuery(
"DELETE FROM u.attendingEvents AS ae WHERE ae.id = :event_id"
);
delete.setParameter("event_id", e.getId());
delete.executeUpdate();
attendingUsers.remove(u);
e.setAttendingUsers(attendingUsers);
update(e);
}
}
Однако, это приводит к org.hibernate.hql.internal.ast.QuerySyntaxException: u.attendingEvents is not mapped [DELETE FROM u.attendingEvents AS ae WHERE ae.id = :event_id]
Exception. Однако я не знаю, как сопоставить его, не удаляя событие (я хочу только удалить записи из таблицы join: event_user.Если я попытаюсь удалить из event_user напрямую, я также получаю то же исключение, что event_user is not mapped
.
Любые идеи, как я мог бы решить эту проблему
EDIT:? Когда я пытаюсь использовать «простой», как я в конечном итоге, как это:
08.01.2014 17:03:02 org.apache.catalina.core.StandardWrapperValve invoke SCHWERWIEGEND: Servlet.service() for servlet [appServlet] in context with path [/tripitude] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ac.tuwien.ase08.tripitude.entity.Event.attendingUsers, could not initialize proxy - no Session] with root cause org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ac.tuwien.ase08.tripitude.entity.Event.attendingUsers, could not initialize proxy - no Session
Мой код:
@Transactional
public void unattend(Event e, User u){
try{
Hibernate.initialize(e.getAttendingUsers());
} catch(Exception ex){}
e.getAttendingUsers().remove(u);
Спасибо, я надеялся, что это так просто, однако это не сработает для меня. Если я только пытаюсь получить доступ к посетителям, посещающим с помощью 'e.getAttendingUsers()', я получаю исключение NullPointerException. Но я знаю, что мне нужно сначала их инициализировать, см. Мое редактирование для того, что произойдет, пожалуйста:/ – Cr0w3
Как я уже сказал в своем ответе: не работайте с объектами, исходящими от я не знаю, где. Получите событие по идентификатору из базы данных с помощью session.find(), получите идентификатор пользователя по базе данных с помощью session.find(), а затем выполните работу с этими двумя прикрепленными объектами. Все это внутри транзакционной службы. –
Спасибо, ты мне очень помог :) Мне пришлось сначала найти как событие, так и пользователя по id, а затем 'Hibernate.initialize (e.getAttendingUsers)' И 'Hibernate.initialize (u.getAttendingEvents)'. После этого я смог удалить :) – Cr0w3