Вопрос по lazy-loading, spring, jpa, hibernate – В Spring с jpa / hibernate, как сохранить сеанс открытым, чтобы избежать отложенных исключений инициализации?

18

В настоящее время я отмечаю коллекции в бинах сущностей как стремящихся избежать получения отложенной инициализации, когда пытаюсь получить доступ к свойствам коллекции после загрузки бина с помощью EntityManager.

Если я вместо этого оставлю коллекцию как отложенную загрузку, как мне сохранить сеанс открытым? Я думал о попытке @Transactional, но даже если бы это работало, я бы не хотел этого делать, потому что кажется неправильным оставлять транзакцию открытой в течение длительного метода.

Ваш Ответ

6   ответов
3

вы должны прочитать об «открытой сессии в поле зрения» шаблон, основная идея которого заключается в том, чтобы сеанс гибернации был открыт в течение всей продолжительности обработки http-запроса. Есть обаспящий специфический а такжевесна Решения - я использовал пружины раньше, и это прекрасно работает.

В вопросе вы упоминаете, что не хотите, чтобы транзакция была открыта в течение длительного времени. Для большинства людей это не проблема, потому что каждый запрос обрабатывается относительно быстро. Однако, если в вашем случае это действительно невозможно, этот шаблон не будет работать для вас. Можете ли вы объяснить, почему вы не хотите, чтобы транзакции оставались открытыми?

5

который, по-видимому, был пропущен, заключается в том, что вы можете построить свой объектный граф на основе своего варианта использования с помощью JOIN.

Это приведет к инициализации объекта, то есть не будет прокси.

Используйте этот подход, если вы контролируете клиента (т.е. вы не создаете открытую службу, публикующую API-интерфейс), потому что вам нужно знать, к какому состоянию обращаются при закрытии сеанса, поскольку транзакция закрыта.

0

но я использовал Hibernate в нескольких разных проектах. Подход, который я выбрал для самого последнего проекта, вырос изОбработка защитной сессии шаблон (в сочетании с сервлетным фильтром), и мы довольны им. Вы можете найти больше шаблонов дизайнаВот.

hibernate.org/238.html больше недоступно. Вот архивная версия:web.archive.org/web/20090309074606/http://hibernate.org/…
0

который прочитал некоторые данные, вы оставляете эту транзакцию открытой. Длительные транзакции не являются большой проблемой (хотя это может зависеть от вашей базы данных), что действительно вызывает проблемы, так как блокировки удерживаются в течение длительного времени, но они могут быть созданы только после того, как вы действительно измените данные в базе данных. Опять же, это зависит от вашей базы данных.

9

https://www.hibernate.org/43.html

По сути, у вас есть несколько вариантов.

- Вы можете использовать & quot; открыть сеанс в представлении & quot; шаблон, в котором вы используете логику в стиле фильтра / перехватчика / AOP, чтобы открыть сеанс, когда начинается логика на стороне сервера, и закрыть его, когда он закончится.

-Вы могли бы осуществлять диалоги, охватывающие несколько циклов запрос-ответ.

Простой старый Servlet Filter - самый простой.

Этот ответ актуален для случаев, когда исключение отложенной инициализации имеет корень в завершенном сеансе Hibernate HTTP-запроса-ответа. Однако могут быть и другие корни.
@lucas Можете ли вы помочь мне с подобной проблемойhere?
Довольно уверенно "открыть сеанс в поле зрения" можно считать анти-паттерном.
1

он будет управлять сессией. В качестве альтернативы, если вы используете Hibernate 3.0.1 или выше, Spring все равно сможет управлять сессией за вас.

Есть SpringSourceзапись в блоге это описывает, как настроить это. Я включил выдержку ниже:

Since Hibernate 3.0.1 (and in the Java Persistence API from the moment it was first released) it became possible for Spring to manage the underlying resource without you having to go through any of the templates that are available for those technologies. This means that even if you are using the Hibernate API directly (for example through SessionFactory.getCurrentSession()), you will still be using a Spring-managed Hibernate Session. The same holds for an EntityManager obtained through a JPA EntityManagerFactory. This is another reason why you don't have to use Spring's HibernateTemplate anymore to get an integrated experience. [...]

The following is the XML that we'll use to assemble the application. As you can see, we're of course still using the Spring way of setting up Hibernate (using the LocalSessionFactoryBean).

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <!– the works –>
</bean>
<bean id="accountRepo" class="com.mycompany.HibernateAccountRepository">
  <constructor-arg ref="sessionFactory"/>
</bean>

Now, as I said before, because of a small change in Hibernate 3.0.1, Spring is able to manage the Hibernate session for you, without you having to go through the Hibernate session. The one thing that was missing was the exception translation. To also get that going, you only need to annotate the repository with the @Repository annotation (provided by Spring) and turn on exception translation using a post processor.

@Repository // from org.springframework.stereotype
public class HibernateAccountRepository implements AccountRepository {
    // see above for full impl…
}
Граница транзакции является ключевой здесь, если вы не используете Spring HibernateTemplate.

Похожие вопросы