Hibernate无法延迟初始化集合”运行时错误

问题描述 投票:0回答:1

这个问题已经问了很多遍,但是我仍然找不到我的用例的解决方案:

  1. 我有一个使用Hibernate 5.x的Struts2应用程序。

  2. 该应用程序是“联系人应用程序”。它具有两个实体:一个“联系人”,可以包含零个或多个“注释”。

  3. 这是我获得联系方式:

    @Override
    public List<Contact> getContacts() {
    //Note: Hibernate 5++ supports Java try-with-resource blocks
    try (Session session = HibernateUtil.openSession()) {
        List<Contact> contacts = session.createQuery("FROM Contact").list();
        return contacts;
        ...
    
  4. 效果很好。直到我尝试这样的东西:

    ObjectMapper mapper = new ObjectMapper();
    jsonString = mapper.writeValueAsString(contacts);
    

错误:

16:05:16.174 [http-nio-8080-exec-2] DEBUG org.apache.struts2.dispatcher.Dispatcher - Dispatcher serviceAction failed
com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.example.contactsapp.models.Contact.notes, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.example.contactsapp.models.Contact["notes"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394) ~[jackson-databind-2.10.0.jar:2.10.0]
    ...
    at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:4094) ~[jackson-databind-2.10.0.jar:2.10.0]
    at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3404) ~[jackson-databind-2.10.0.jar:2.10.0]
    at com.example.contactsapp.actions.ContactsAction.getContacts(ContactsAction.java:36) ~[classes/:?]
    ...

可能的解决方案

  1. 我愿意NOT想要更改为FetchType.Eager

  2. 由于我不使用Spring,所以不能使用@TransactionalOpenSessionInView。但我很想知道是否有仅适用于Hibernate的产品。

  3. 这些是我尝试过的(主要基于How to solve the “failed to lazily initialize a collection of role” Hibernate exception:]

    @Override
    public List<Contact> getContactsFetchAll() {
      //Note: Hibernate 5++ supports Java try-with-resource blocks
      try (Session session = HibernateUtil.openSession()) {
        // Jackson mapper.writeValueAsString() => "failed to lazily initialize a collection" 
        // List<Contact> contacts = session.createQuery("FROM Contact").list();
    
        // Plan A: Causes same "failed to lazily initialize a collection" runtime error
        // List<Contact> contacts = session.createQuery("FROM Contact").list();
        // Hibernate.initialize(contacts);
    
        // Plan B: Still no-go: returns [] empty set
        // List<Contact> contacts = session.createQuery("SELECT c FROM Contact c JOIN FETCH c.notes n").list();
    
        // Plan C: Same: "failed to lazily initialize a collection of role..."
        // Query query = session.createQuery("FROM Contact");
        // Hibernate.initialize(query);
        // List<Contact> contacts = query.list(); 
    
        // Plan D: Same: "ERROR: failed to lazily initialize a collection of role"
        // List<Contact> contacts = session.createQuery("FROM Contact").list();
        // for (Contact c : contacts) {
        //    Set<Note> n = c.getNotes();
        // }
           return contacts;
        }
     }
    

问:有什么建议吗?

问:您需要任何其他信息吗?

java hibernate lazy-loading
1个回答
0
投票

如果您在实体配置中使用懒惰初始化来实现OneToMany映射,并且在某些情况下您希望尽快获取集合。我认为您可以使用@NamedQuery在单个查询中提取列表(在您的情况下为“左联接”)。

© www.soinside.com 2019 - 2024. All rights reserved.