Hibernate - 从@ManyToMany删除查询

时间:2014-01-08 15:04:04

标签: java mysql hibernate

我有两个对象:事件和用户。两者都互相提及:

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

好的,现在我遇到了我希望用户能够无人参加活动的情况。到目前为止,我已经尝试了几件事,但看起来只有查询才有效。我想使用查询的原因是:我无法使用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]异常。然而,我不知道如何在不删除事件的情况下映射它(我只想删除连接表中的条目:event_user。如果我尝试直接从event_user中删除,我也会得到相同的异常,{{1 }}

我有什么想法可以解决这个问题吗?

编辑:当我尝试使用&#39;简单&#39;我的结局是这样的:

event_user is not mapped

我的代码是:

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

1 个答案:

答案 0 :(得分:2)

您不需要任何查询。您需要做的就是从要无人参与的事件的使用列表中删除用户。为了使你的对象图形连贯,你也应该从用户的事件中删除事件,但是Hibernate不关心它,因为它是关联的反面:

public void unattend(Event e, User u){
    // mandatory:
    e.getUsers().remove(u);
    // optional:
    u.getEvents().remove(e);
}

以上假设ue是附加实体,当然。如果它们不是,那么,在事务中,首先从数据库中通过ID获取它们,并使用返回的实体调用上述方法。