Прямо сейчас я прошу this question на стеке переполнение и that one на codereview.Я использую Hibernate-Sessions неправильно?
Это заставляет меня думать, если я понял, как использовать сеансы 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"
Чтобы сохранить это можно было бы сделать что-то вроде этого: (обратите внимание, что один из инструментов не имеет идентификатора).
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()
, но это не будет очень объектно-ориентированный язык ..
Это хороший намек, но, к сожалению, я действительно не отвечаю на мой вопрос. Как это будет выглядеть в моем сценарии, когда я должен «предварительно хранить» некоторые объекты, прежде чем сохранять свой «ToolSet». Я просто не знаю, как я должен это делать. – displayname
Хорошо согласен. Hibernate.openSession() всегда будет открывать новый сеанс, так как вы указываете, что это может быть непрактичным, если вы работаете с одними и теми же объектами в двух разных сеансах. Вам лучше использовать sessionFactory.getCurrentSession(), который возвращает сессию, связанную с контекстом (и ее не нужно закрывать). По умолчанию контекст привязан к текущему потоку, поэтому обычно это означает, что сеанс будет использоваться повторно во всех ваших методах. Вот почему я предложил использовать Spring с sessionFactory.getCurrentSession() - он будет автоматически повторно использовать сеанс для всех вызовов в запросе. – lars