spring-boot - 没有惰性的 Spring + Hibernate = LazyInitializationException
问题描述
我想从没有惰性对象/子项的表中加载所有对象并将它们列出在页面上(Thymeleaf 模板),但我每次都得到一个 LazyInitializationException。我试图将 Hibernate 实体对象转换为不包含惰性/不需要的对象但结果相同的 POJO。我也试过open-in-view parameter
设置为假...
简单的例子:
家长:
@Entity
public class DocumentDbe implements Serializable {
public DocumentDbe(){
}
@Id
@Column(name = "id", updatable = false, nullable = false)
private Long id;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
private DocumentFileDbe documentFile;
....
}
孩子:
@Entity
public class DocumentFileDbe implements Serializable {
public DocumentFileDbe(){}
@Id
@Column(name = "id", updatable = false, nullable = false)
private Long id;
@Column
@Lob
private byte[] documentData;
...
}
POJO:
public class DocumentDto implements Serializable {
public DocumentDto(){
}
public DocumentDto(DocumentDbe doc){
this.id = doc.getId();
}
....
}
控制器:
@GetMapping("/list")
String getList(Model model) {
List<DocumentDbe> docs;
List<DocumentDto> data = new ArrayList<>();
try (Session ses = sessionFactory.openSession()) {
docs = ses.createQuery("FROM DocumentDbe").list();
docs.forEach(doc -> {
data.add(new DocumentDto(doc));
});
}
model.addAttribute(MODEL_LIST_DATA, data);
return "list";
}
编辑:抛出异常:
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/list.html]")] with root cause
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
EDIT2:
与DocumentDbe
另一个对象的关系(这次是EAGER,所以我没有注意它),它DocumentDbe
再次引用了..链式关系并创建了LazyInitializationException ...
EDIT3:
虽然
这是修改和工作控制器,没有 POJO:
@GetMapping("/list")
String getList(Model model) {
List<DocumentDbe> docs;
try (Session ses = sessionFactory.openSession()) {
docs = ses.createQuery("FROM DocumentDbe ORDER BY id DESC").list();
docs.forEach(doc -> {
doc.setDocumentFile(null);
doc.getHistory().forEach(log ->{
log.setDocument(null);
});
});
}
model.addAttribute(MODEL_ADMIN_DATA, docs);
return "list";
}
解决方案
在课堂DocumentDbe
上,您将关系标记为 Lazy。在默认关系中@ManyToOne
并且@OneToOne
是 EAGER,所以如果你不想要 Lazy,你必须改变
@OneToOne(cascade = CascadeType.PERSIST)
如果你也想要 @lob 一样渴望:
@Lob
@Basic( fetch = FetchType.EAGER )
推荐阅读
- javascript - 是否有 Javascript/HTML 表单基础网页/帖子?建了一个 Excel 表格,想把它放在网页上
- unity3d - 何时在 Unity3D 中使用 transform.position 和rigidbody.position
- php - 如何将phpmailer连接到联系表格
- java - OneSignal 通知处理程序调用“startActivity”
- ios - Alertview 操作 快速导航到下一个视图控制器后
- mysql - 错误:查询结构与函数结果类型不匹配
- android - 如何在单行上保持两个 TextInputLayouts 一致的宽度
- linux - 选择特定路线/路径到目的地地址
- mysql - 使用数据库管理工具从 ubuntu 服务器连接 mysql 的问题
- r - 如何重新排列R中的单个单元格?