@Transactional annotation is used when you want the certain method/class to be executed in a transaction.
Let's assume buyer wants to transfer 10$ to seller. What happens is:
1-> We decrease buyer's account by 10$
2-> We add 10$ to seller's account
Then the exception is thrown after succeeding 1) and before executing 2). Now we would have some kind of inconsistency because Buyer lost 10$ while seller got nothing. Transactions means all or nothing. If there is an exception thrown somewhere in the method, changes are not persisted in the database. Something called rollback happens.
If you don't specify @Transactional, each DB call will be in a different transaction.
From the previous post, JPA specification says that in case you are trying to fetch a relationship, which is lazily loaded, you must have declared transaction. Otherwise, LazyInitializationException will be the one of the most common exceptions you will face when working with Hibernate.
- People recommend updating the association's FetchType to EAGER. Of course, this resolves the LazyInitializationException, but it also adds performance issues that will emerge in practice. Hibernate will always fetch the association if the FetchType is set to EAGER, even if you don't utilize it in your scenario. This certainly adds overhead to your program, slowing it down.
- Another suggestion you should avoid is to set the hibernate.enable_lazy_load_no_trans configuration parameter in the application.properties file to true. This parameter tells Hibernate to open a temporary Session when no active Session is available to initialize the lazily fetched association. This increases the number of used database connections, database transactions and the overall load on your database.
- Executing a Criteria Query with one or more LEFT JOIN FETCH clauses is the simplest way to load an entity with all required relationships. This enables Hibernate to collect all connected entities referenced in the LEFT JOIN FETCH clause, in addition to the entity referenced in the projection. See the related post
- Use a DTO projection instead of entities. DTOs don’t support lazy loading, and you need to fetch all required information within your service layer.