Search code examples
javaspringspring-bootjpatransactional

Do service layer always must be transactional in spring?


I have very simple application in spring including 1 model class for db table, 1 jpa repository class 1 service and 1 controller class.

My service class is:

@Transactional
@Service
public class SomeService {

    private ServiceRepository serviceRepository;

    @Autowired
    public serviceService(ServiceRepository serviceRepository) {
        this.serviceRepository = serviceRepository;
    }


    public void getServiceById(Long id) {
        Model model = serviceRepository.getOne(id);
        return....
    }

}

It is working with @Transactional annotation. But if i delete that i get

org.hibernate.LazyInitializationException: could not initialize proxy

What if i dont want any transactional method or class, Why do i have to make it transactional?


Solution

  • This exception occurs because you try to access objects that haven't been loaded inside your transaction.

    When you leave transaction, you cannot load objects from database anymore. But the transaction isn't mandatory.

    I think you have objects with OneToMany/ManyToMany relation that is lazyLoaded. Because your service is not transactional, the connection to DB is closed, and you cann't access to objects anymore.

    You have 2 options :

    • Set Eager fetch to your objects (your objects are always loaded).
    • Make your service transactional (the objects will be loaded on demand).

    You should be aware of performance issues when you activate lazy loading (the default option). It really depend on your business logic if it relevant to use or not, but it is really better to try to not have multiple access to DB.

    You can also check to Entity Graph for advanced customizations : https://www.baeldung.com/jpa-entity-graph

    Also, when developing, enable hibernate SQL traces to see what is happening on background : https://www.mkyong.com/hibernate/hibernate-display-generated-sql-to-console-show_sql-format_sql-and-use_sql_comments/