Usando Hibernate 5, Spring 4
Considere los códigos a continuación y el mapeo entre dos entidades:
clase de usuario
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user") private TruckOwner truckOwner;// getter setters debajo
Clase TruckOwner
@OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) private User user;// getter setter debajo
Cuando mi código intenta actualizar los valores dentro de la clase de user como el siguiente código: clase UserServiceImpl
@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); } Al llamar a userDAO.merge(user); Aparece el siguiente error: la entidad no transitoria tiene una identificación nula: com.mymodel.TruckOwner
Estoy enfrentando este tipo de problema en muchos lugares de mi proyecto, ayúdenme con una solución adecuada a este problema y ¿por qué la clase TruckOwner tiene todo nulo establecido por hibernación?
El modo entusiasta no es una solución si está creando una aplicación de producción. El problema es que su sesión ya está cerrada cuando intenta obtener TruckOwner. Intente propagar la sesión a todos los métodos resetPassword .
Deberíamos conocer la implementación del método de userdao merge , pero supongo que se llama el método de merge de la interfaz de Session de hibernación. En cualquier caso, el objeto no transitorio es el objeto TruckOwner ; hibernat no recuperará el objeto cuando llame a System.out.println(user.getTruckOwner().getTruckOwnerId()); además, en ese momento está fuera de la sesión de hibernación y si llama a cualquier otro captador de truckOwner excepto getTruckOwnerId(), debería obtener la org.hibernate.LazyInitializationException (o similar ... no recuerdo correctamente)
Supongo que tienes 2 opciones:
userDAO.findById(userId); debe fetch el objeto truckOwner dentro de la sesión de hibernación llamando a cualquier otro método dentro de userDAO.findById(userId); implementación y dentro de la sesión de hibernaciónespero que sea util
Ángel
Prueba esto para la clase de camiones:
@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; } }Y esto para la clase User:
@Entity @Table(name = "user") public class User{ private TruckOwner truckOwner; @OneToOne(fetch = FetchType.LAZY) @PrimaryKeyJoinColumn public TruckOwner getTruckOwner() { return this.truckOwner ; } }