I think that you are doing something wrong in your DAO class, because you are opening a session and transaction inside your method and probably inside each of the DAO methods.
It has a cost in productivity and poor conceptually, a transaction should group a set of operations that will be completely successful or fail. In most cases, the database transaction will be associated with the entire business operation, in this case with a REST request. Something like
POST / user
@ RestController.createUser
open transaction
UserDAO.saveUser
make a transaction
answer
Also, if you look at your code, you open a transaction and then close.
tx = session.getTransaction(); session.beginTransaction(); tx.commit();
In this case, you query the database so that the transaction is not needed at all.
Transactions are a cross-cutting issue in your application, and given that you are already using Spring, you should look at the @Transactional annotation (or its xml equivalent) to achieve the transaction with AOP (Spring creates an aroud aspect). This will make your code more readable and maintainable.
@ManojP's answer is good and bad. I think you should avoid bidirectional relationships whenever possible, because it complicates the design. My advice is this: always start with a one-way relationship, and if you find a case where you cannot avoid it, use it. The good thing is that using laziness shows you when he does it:
List<User> users = profession.getUsers();
This line of code must be outside the DAO. It happens that you have a list of users marked as lazy (by default), and then, when you select professions with a request for criteria, the selection by professions of the table is launched, and each of the Profession objects is created using instead of the simplest collection. When you call the profession .getUsers (), the new element is selected by a trigger on the user table, where professional_id = profession.getId (). So:
- List of results = criteria .list ();
- Select * from Profession
- professionA.getUsers ();
- Select * from user, where profession_id =: professionA.getId ()
But be careful! if you have a collection of professions (for example, I think you have one because you are returning the list) and repeat each profession and specify a list of users that you will do:
- List of results = criteria .list ();
- Select * from Profession
- for each profession β profession.getUsers
- Select * from user, where profession_id =: professionA.getId ()
- Select * from user, where profession_id =: professionB.getId ()
This will have poor performance.
@Farvilain's answer is good. But in this case, you will always receive a Profession with a collection of Users, because inside your DAO you always use FetchMode.JOIN, and then lose the advantage of laziness. So, if you always want a list of users when requesting Professions, use lazy = true for the collection of users, but keep in mind what costs may be incurred (if the User does not have lazy collection A, when you request Professions you will also get a list of users plus compilation A). If you do not want this, you might have this signature:
public List<Profession> getProfessionById(Long id, FetchMode fetchMode) throws Exception
This is not very nice, but shows that the DAO client can select fecth mode.