Hibernate is the most used ORM framework by Java developers, but there are still many misunderstandings about how it works and its best practices.
ORM provides great abstraction between objects and DB, and that is also the problem. Developers tend to forget that queries are expensive and that accessing DB like accessing common objects in memory creates an unpredictable number of DB queries.
One of the ways to prevent it from happening is to monitor queries that a code creates, and it is a tricky thing to do. You can set the level of Hibernate login to log DB calls and track it like that. The problem with that solution is that it is implicit, not part of the code, and you need to do it manually.
A more elegant solution is to create an interceptor (QueryCountInterceptor) and thread-local variable (like AppThread) that will intercept hibernate prepare statements and process them. QueryCountInterceptor is great for code debugging. It is also a learning tool for newcomers into Hibernate. Besides that, it can be integrated with tests. For example, after each tested method, assert the number of queries that have been performed. In this way, you can avoid the situation that a code change unexpectedly changes method performance.