现在我在代码审核上询问堆栈溢出和this question上的that one。
这让我想到如果我已经理解了如何使用Hibernate会话。我会尝试做这个简短的事情:
假设您有多种语言的工具和工具说明。因此,您有Tool
,ToolDescription
和Language
表。现在进一步假设您给客户提供了一组工具的可能性,但不仅仅是现有工具,他还可以通过创建一个新名称来创建新工具。当客户端将数据发送到服务器时,它会尝试存储这组工具,但必须先保存新工具。它看起来像这样:
客户发送:
ToolSet
id:1
Tool1
id:2
en:"My Hammer"
de:"Mein Hammer"
Tool2
id:null
en:"My new Tool"
de:"Mein neues Werkzeug"
要保存此功能,必须执行以下操作:(请注意,其中一个工具没有ID)。
toolSet = getToolSet(toolSetDto.getId());
if(toolSetDto.tool1 != null) {
tool1Dto = toolDescriptionRepository.updateOrSaveNewTool(toolSetDto.getTool1());
}
if(toolSetDto.tool2 != null) {
tool2Dto = toolDescriptionRepository.updateOrSaveNewTool(toolSetDto.getTool2());
}
// New session ..
session = Hibernate.openSession();
session.beginTransaction();
tool1 = session.get(Tool.class, tool1Dto.getId());
tool2 = session.get(Tool.class, tool2Dto.getId());
toolSet.setTool1(tool1);
toolSet.setTool2(tool2);
session.getTransaction().commit();
session.close();
对于updateOrSaveNewTool(ToolDTO toolDto)
我们有类似的内容:
Session session = Hibernate.openSession();
Tool tool = null;
if(toolDto.getId() != null) {
// Tool does already exist..
tool = session.get(Tool.class, toolDto.getId());
} else {
// Store a new tool ..
session.beginTransaction();
tool = new Tool();
session.save(tool);
ToolDescription toolDescription = new ToolDescription(tool, getDefaultLanguage());
session.save(toolDescription);
session.getTransaction().commit();
}
session.close();
这将在一个RPC调用中打开多个会话,例如由于我的问题,我有here我不确定我是否应该这样做。 我可以获得缓存问题吗?
有人可以向我解释一下如何使用Hibernate会话吗?我知道,他们应该执行/处理一个工作单元,但这并不能解释我是否应该为每个请求打开多个会话。
我当然可以 un 封装updateOrSaveNewTool()
并且可以工作使用原始实体对象,并且不必在get(Tool.class, tool1Dto.getId())
之后执行另一个updateOrSaveNewTool()
,但这不会非常面向对象..
答案 0 :(得分:1)
Hibernate会话应该被视为“工作单元”。如果您的工作单元涉及创建一些实体并稍后使用它们,那么最好对所有这些操作使用单个会话。更好的是,您将这些转换为单个事务,因此如果一个步骤失败,则回滚前面的步骤。 通常,工作单位是单个请求中发生的任何事情。
您所看到的是一个常见问题,根据您的技术堆栈,它会有所不同。
如果您在Java EE容器中,例如Wildfly,则可以让容器为您管理实体管理器。因此,您只需注入一个可以使用的EntityManager(即:“会话”已经为您打开,并且当您不再需要它时将关闭)。
另一种常见方法是每个请求使用一个会话,由您自己管理:您有一个过滤器(或类似的东西),一旦收到请求就会打开一个会话,并在响应准备就绪时关闭。您将其存储在本地线程中,以便每个请求都有自己的会话。
最后,如果您使用的是Spring,您可以将EntityManager的维护委派给它,就像您使用Java EE容器一样。