Dropwizard没有懒惰地初始化角色集合

时间:2016-03-05 09:49:17

标签: java hibernate jackson dropwizard

使用dropwizard 0.9.2和dropwizard-hibernate 0.9.2,我正在尝试使用hibernate检索由@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尝试序列化对象时,hibernate会话被关闭)但是不应该把库jackson-datatype-hibernate4(这是dropwizard-hibernate的依赖关系)来处理这个问题。为我自动(重新打开一个会话并实现收集)?如果不是这个库正在做什么以及大多数dropwizard应用程序如何解决这个问题(EAGER提取不是一个选项)?

的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;
}

DAO:

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

1 个答案:

答案 0 :(得分:0)

阅读文档,这可能是设计出来的:

  

重要

     

Hibernate会话在您的资源之前关闭   方法的返回值(例如,数据库中的Person),其中   表示您的资源方法(或DAO)负责初始化   所有懒惰的集合等,在返回之前。除此以外,   你会在你的模板中抛出一个LazyInitializationException(或者   杰克逊产生的零值。

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

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

  

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

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

我希望有所帮助。

阿图尔

相关问题