Introduction
I’ve already written about the Open Session in View Anti-Pattern, so now it’s time to add another Hibernate fetching bad practices. Although the
hibernate.enable_lazy_load_no_trans
configuration property is a lesser-known setting, it’s good to know why you shouldn’t employ it in your data access layer code.What does it do?
By default, this property is disabled and, to enable it, you need to provide the following configuration property:
1
2
3
| < property name = "hibernate.enable_lazy_load_no_trans" value = "true" /> |
Considering the following entities:
With this configuration property in place, the following code snippets can be executed without throwing any
LazyInitializationException
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| List<PostComment> comments = null ; EntityManager entityManager = null ; EntityTransaction transaction = null ; try { entityManager = entityManagerFactory() .createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); comments = entityManager.createQuery( "select pc " + "from PostComment pc " + "where pc.review = :review" , PostComment. class ) .setParameter( "review" , review) .getResultList(); transaction.commit(); } catch (Throwable e) { if ( transaction != null && transaction.isActive()) transaction.rollback(); throw e; } finally { if (entityManager != null ) { entityManager.close(); } } for (PostComment comment : comments) { LOGGER.info( "The post title is '{}'" , comment.getPost().getTitle()); } |
Without the
hibernate.enable_lazy_load_no_trans
configuration property in place, the comment.getPost().getTitle()
line would throw a LazyInitializationException
because the comments
collection was not initialized, and the Persistence Context is already closed, along with the database connection that fetched the post
entity.
Behind the scenes, a temporary
Session
is opened just for initializing every post
association. Every temporary Session
implies acquiring a new database connection, as well as a new database transaction.
The more association being loaded lazily, the more additional connections are going to be requested which puts pressure on the underlying connection pool. Each association being loaded in a new transaction, the transaction log is forced to flush after each association initialization.
Reference:
0 komentar: