【问题标题】:Dropwizard failed to lazily initialize a collection of roleDropwizard 无法懒惰地初始化角色集合
【发布时间】:2016-03-05 09:49:16
【问题描述】:

使用 dropwizard 0.9.2 和 dropwizard-hibernate 0.9.2,我正在尝试使用休眠检索由 @OneToMany 映射的集合。不幸的是,我遇到了这个异常:

com.fasterxml.jackson.databind.JsonMappingException: failed to lazily 
initialize a collection of role: com.ng.Computer.parts, could not 
initialize proxy - no Session

我确实理解为什么会发生这种情况(当杰克逊尝试序列化对象时,休眠会话关闭)但库 jackson-datatype-hibernate4(它是 dropwizard-hibernate 的依赖项)不应该处理这个问题自动为我(重新打开会话并实现集合)?如果不是这个库在做什么,大多数 dropwizard 应用程序如何解决这个问题(EAGER fetching 不是一个选项)?

Pom.xml

  <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-core</artifactId>
      <version>0.9.2</version>
  </dependency>

  <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-testing</artifactId>
      <version>0.9.2</version>
  </dependency>

  <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-hibernate</artifactId>
      <version>0.9.2</version>
  </dependency>

型号

@Entity
public class Computer {

    @Id
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    private String name;

    @JsonIgnore
    @OneToMany
    public List<Part> parts;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Part> getParts() {
        return parts;
    }

    public void setParts(List<Part> parts) {
        this.parts = parts;
    }
}

@Entity
public class Part {
    @Id
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

资源:

@GET
@UnitOfWork
@Timed
public Response list() {

    Computer computer = computerDAO.findById(1L);

    Response response = Response.ok(computer.getParts()).build();

    return response;
}

道:

public class ComputerDAOImpl extends AbstractDAO<Computer> implements    
ComputerDAO{

    public ComputerDAOImpl(SessionFactory sessionFactory) {
        super(sessionFactory);
    }

    public Computer findById(Long computationId) {
        Computer computer = get(computationId);
        return computer;
    }
}

【问题讨论】:

    标签: java hibernate jackson dropwizard


    【解决方案1】:

    阅读文档,这可能是设计使然:

    重要

    Hibernate 会话在您的资源之前关闭 方法的返回值(例如,数据库中的 Person),其中 表示您的资源方法(或 DAO)负责初始化 返回之前所有延迟加载的集合等。除此以外, 您将在模板中抛出 LazyInitializationException(或 Jackson 产生的 null 值)。

    因此,您的代码似乎需要专门负责加载这些部件,而不是使用它来运行。

    或者通过快速查看文档来判断,您的问题是 UnitOfWork 注释。这个负责关闭你的会话。阅读文档:

    这将自动打开一个会话,开始一个事务,调用 findByPerson,提交事务,最后关闭会话。 如果抛出异常,则事务回滚。

    结合上述:如果你想使用 UnitOfWork,你必须自己实现延迟加载,否则 UnitOfWork 会在你到达之前关闭你的会话。如果您不想使用它,则必须以不同的方式处理您的交易。

    希望对你有帮助。

    阿图尔

    【讨论】:

      猜你喜欢
      • 2011-07-21
      • 2021-01-30
      • 1970-01-01
      • 2016-03-30
      • 2014-05-03
      • 2021-06-15
      相关资源
      最近更新 更多