当前位置: 首页 > 知识库问答 >
问题:

从惰性获取列表中删除-Hibernate

丌官开宇
2023-03-14
@Entity
@Table(name = "User")
public class User implements Serializable {

    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "attendingUsers")
    private List<Event> attendingEvents = new ArrayList<Event>();
}
@Entity
@Table(name = "Event")
public class Event implements Serializable {

    @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>();
}

当然,这些列表有setter和getter。现在我想实现以用户身份不参加这些事件的可能性。因此,我尝试了以下方法:

public void unattend(Event e, User u){
    List<User> attendingUsers = getAttendingUsers(e.getId());
    List<Event> attendingEventsForUser = userService.getEvents(u.getId());
    if(attendingUsers.contains(u)){
        e.getAttendingUsers().clear();
        u.getAttendingEvents().clear();
        attendingUsers.remove(u);
        attendingEventsForUser.remove(e);
        e.getAttendingUsers().addAll(attendingUsers);
        u.getAttendingEvents().addAll(attendingEventsForUser);
        update(e);
        userDAO.update(u);
    }
}

我得到的例外情况如下:

尽管我使用了一些方法来确保执行惰性提取:

public List<User> getAttendingUsers(Long id){
    Query query = sessionFactory.getCurrentSession().createQuery(
            "SELECT u FROM User AS u LEFT JOIN u.attendingEvents AS ae WHERE ae.id = :id");
    query.setParameter("id", id);

    List<User> l = (List<User>)query.list();

    return l;
}
    @Override
public List<Event> getEvents(Long id) {
    Query query = sessionFactory.getCurrentSession().createQuery(
            "SELECT e FROM Event AS e LEFT JOIN e.attendingUsers AS au WHERE au.id = :id");
    query.setParameter("id", id);

    List<Event> l = (List<Event>)query.list();

    return l;
}
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();

    Query query2 = sessionFactory.getCurrentSession().createQuery(
            "SELECT e FROM Event AS e LEFT JOIN FETCH e.attendingUsers AS au WHERE au.id = :id");
    query2.setParameter("id", u.getId());

    List<Event> attendingEventsForUser = (List<Event>)query2.list();

    if(attendingUsers.contains(u)){
        attendingUsers.remove(u);
        attendingEventsForUser.remove(e);
        e.setAttendingUsers(attendingUsers);
        u.setAttendingEvents(attendingEventsForUser);
        update(e);
        userDAO.update(u);
    }
}

共有1个答案

唐茂实
2023-03-14

您正在尝试访问事务之外的惰性集合。您可以使用@transaction注释相关的方法,也可以使用fetch联接:

SELECT e FROM Event AS e LEFT JOIN FETCH e.attendingUsers ...

在事务中工作通常更好,因为只有在需要时才提取相关实体。

Edit:异常可能源于'unattend'方法中的if子句,在该子句中可以访问列表:e.getAttendingUsers()。我将把它从控制器移到事务性服务中,比如EventService

 类似资料:
  • 我有一个简单的查询很好地工作了一段时间,现在我将代码中的一些内容改为: (hibernate.cfg.xml) 和以下代码: 提交后,result对象不会加载列表(即从开始) 如果我执行在提交前,它会保持加载状态,而且,如果我使用它工作得很好。(但这不是它应该如何工作(让它在使用时打开并加载),createAlias应该一如既往地正常工作) 看起来DetachedCriteria的createAl

  • 给定一个元素列表,我想获取具有给定属性的元素并将其从列表中删除。我找到的最佳解决方案是: 是否可以在lambda表达式中组合get和删除?

  • 我正在使用CSVHelper库读取CSV文件。但这不是你想要的 请参阅以下代码 上面方法中的CSV.getRecords使用yield返回,并在每一个CSV行被读取后立即返回,而不是等到整个CSV文件被读取后再返回(从CSV流数据) 我有一个consumer类,顾名思义,它使用Read方法返回的数据。 下面是调用方 希望我没有失去你。 我面临的问题就在下面 由于上面的数据变量是IEnumerabl

  • 问题内容: 如果我需要从List中删除一个对象(假设字符串“ abc” linkedList或ArrayList),则可以删除哪一个?(我认为两者都是相同的) ,如果我使用Linkedlist和arraylist,那么时间和空间的复杂度是多少 (我相信两者的时间复杂度都为O(n)相同) 问题答案: 两者都具有相同的时间复杂度-O(n),但是恕我直言,该版本会更快,尤其是在大型列表中,因为当您从数组

  • 问题内容: 在遍历列表时,我想根据条件删除列表中的项。请参见下面的代码。 这给了我一个例外。 如何才能做到这一点? 问题答案: 您需要使用和调用上,而不是使用循环。

  • 问题内容: 如果我有词典列表,请说: 并且我想删除具有2(或name )的字典,以编程方式解决此问题的最有效方法是什么(也就是说,我不知道列表中条目的索引,因此它可以)只是被弹出)。 问题答案: 编辑 :由于对此代码的性能提出了一些疑问(一些基于对Python的性能特征的误解,一些基于超出给定规范的假设,即列表中仅存在一个dict,其key的值为2) id”),我希望在此方面给您保证。 在旧的Li