使用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;
}
}
答案 0 :(得分:0)
阅读文档,这可能是设计出来的:
重要
Hibernate会话在您的资源之前关闭 方法的返回值(例如,数据库中的Person),其中 表示您的资源方法(或DAO)负责初始化 所有懒惰的集合等,在返回之前。除此以外, 你会在你的模板中抛出一个LazyInitializationException(或者 杰克逊产生的零值。
因此,您的代码似乎需要专门负责加载部件,而不是使用此代码运行。
或者通过快速查看文档来判断,您的问题是UnitOfWork注释。这个人负责关闭你的会议。阅读文档:
这将自动打开一个会话,开始一个事务,调用 findByPerson,提交事务,最后关闭会话。 如果抛出异常,则回滚事务。
结合上述内容:如果您想使用UnitOfWork,您必须自己实现延迟加载,因为UnitOfWork会在您到达之前关闭您的会话。如果您不想使用它,则必须以不同方式处理您的交易。
我希望有所帮助。
阿图尔