Using Hibernate 5, Spring 4
Please consider below codes and mapping between two entities:
User class
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
private TruckOwner truckOwner;
//getter setters below
TruckOwner class
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
//getter setter below
When my code tries to update values inside user class like below code:
UserServiceImpl class
@Override
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public void resetPassword(Long userId,String newPassword) {
User user = userDAO.findById(userId);
user.setPassword(newPassword);
System.out.println(user.getTruckOwner().getTruckOwnerId());
userDAO.merge(user);
}
When calling userDAO.merge(user); I get below error:
non-transient entity has a null id: com.mymodel.TruckOwner
I am facing this kind of problem in many places in my project, please help me with a proper solution to this problem and why is TruckOwner class has everything null set by hibernate?
Eager mode is not a solution if you are making a production application. Problem is in your session is already closed when your are trying to getTruckOwner. Try to propagate session to all resetPassword method.
We should know the implementation of the userdao merge method but I guess it's called the merge method of hibernate Session interface
In any case the not transient object is the TruckOwner object; hibernat will not fetch the object when you call System.out.println(user.getTruckOwner().getTruckOwnerId()); moreover in that point you are out from hibernate session and if you call any other getter of truckOwner except getTruckOwnerId() you should get the org.hibernate.LazyInitializationException (or similar.. I don't remember correctly)
I guess you have 2 option:
userDAO.findById(userId); you should fetch the truckOwner object inside the hibernate session by calling any other method inside the userDAO.findById(userId); implementation and inside the hibernate sessionI hope it's useful
Angelo
Try this for the truck class:
@Entity
@Table(name = "truckOwner")
public class TruckOwner{
...
private User user;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "truckOwner", cascade = CascadeType.ALL)
public User getUser() {
return this.user;
}
}
And this for the User class:
@Entity
@Table(name = "user")
public class User{
private TruckOwner truckOwner;
@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
public TruckOwner getTruckOwner() {
return this.truckOwner ;
}
}