【问题标题】:Error when It implements a create - HHH000437 Attempting to save one or more实现创建时出错 - HHH000437 尝试保存一个或多个
【发布时间】:2020-09-28 00:24:13
【问题描述】:

当我在前端并实现创建时出现下一个错误。仅当我在表 EmpleadoRol 中创建具有属性“id_empleado_rol”、“rol_Id”和“empleado_Id”的字段时才会发生这种情况。

020-06-08 16:52:41.155  WARN 15382 --- [nio-8080-exec-9] o.h.a.i.UnresolvedEntityInsertActions    : HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities.
    Unsaved transient entity: ([com.jamesferrer.consultorio.apirest.models.entity.Empleado#<null>])
    Dependent entities: ([[com.jamesferrer.consultorio.apirest.models.entity.EmpleadoRol#<null>]])
    Non-nullable association(s): ([com.jamesferrer.consultorio.apirest.models.entity.EmpleadoRol.empleado])

这是我的实体 Empleado:

@Entity
@Table(name="empleados")
public class Empleado implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id_empleado")
    private Integer idEmpleado;

    @Column(nullable=false)
    @NotEmpty(message = "no puede estar vacio.")
    @Size(min=3, max=50, message = "debe tener un tamaño entre 3 y 50 caracteres")
    private String nombre;

    ...

    @ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name="empleados_roles", joinColumns=@JoinColumn(name="empleado_Id"), 
    inverseJoinColumns=@JoinColumn(name="rol_Id"),
    uniqueConstraints= {@UniqueConstraint(columnNames={"empleado_Id", "rol_Id"})})
    private List<Rol> roles;

    @NotNull(message="el tipo de identificación no puede estar vacia.")
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="tipo_Identificacion_Id")
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    private TipoIdentificacion tipoIdentificacion;

    ...

这是我的实体 EmpleadoRol:

@Entity
@Table(name = "empleados_roles")
public class EmpleadoRol implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_empleado_rol")
    private Integer idEmpleadoRol;

    @NotNull(message="no puede estar vacio!")
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="rol_Id")
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    private Rol rol;

    @NotNull(message="no puede estar vacio!")
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="empleado_Id")
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    private Empleado empleado;

    ...

这是我的 IEmpleadoDao

@Repository
public interface IEmpleadoDao extends JpaRepository<Empleado, Integer>{

....

    @Query(value="SELECT nombre FROM(SELECT nombre FROM empleados e LEFT JOIN empleados_roles er ON e.id_empleado = er.empleado_Id WHERE nombre like %?1% GROUP BY nombre HAVING count(empleado_Id) <= 1) val", nativeQuery=true)
     <T> List<T> findNotRepeatEmpleado(String term1, Class<T> type);

}

这是我的控制器:

@RestController
@RequestMapping("/api")
public class EmpleadoRolRestController {

...

@Secured("ROLE_ADMIN")
    @PostMapping("/perfiles")
    public ResponseEntity<?> create(@Valid @RequestBody EmpleadoRol empleadoRol, BindingResult result){

        EmpleadoRol empleadoRolNew = null;
        Map<String, Object> response = new HashMap<>();

        if (result.hasErrors()) {
            List<String> errors = result.getFieldErrors()
                    .stream()
                    .map(err -> "El campo '" + err.getField() + "' " + err.getDefaultMessage())
                    .collect(Collectors.toList());

            response.put("errors", errors);
            return new ResponseEntity<Map<String, Object>>(response, HttpStatus.BAD_REQUEST);
        }

        try {

            empleadoRolNew = empleadoRolService.save(empleadoRol);

        } catch(DataAccessException e) {
            response.put("mensaje", "Error al crear el registro en la base de datos");
            response.put("error", e.getMessage().concat(": ").concat(e.getMostSpecificCause().getMessage()));
            return new ResponseEntity<Map<String, Object>>(response, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        response.put("mensaje", "El perfil ha sido asignado con éxito!");
        response.put("empleadoRol", empleadoRolNew);
        return new ResponseEntity<Map<String, Object>>(response, HttpStatus.CREATED);
    }

@Secured("ROLE_ADMIN")
    @GetMapping("/perfiles/filtrar-empleados/{term1}")
    public List<EmpleadoNombre> filtrarEmpleados(@PathVariable String term1){

        return empleadoService.findNotRepeatEmpleado(term1, EmpleadoNombre.class);
    }

我希望有人可以帮助我。谢谢!

【问题讨论】:

    标签: java spring jpa spring-data-jpa persistence


    【解决方案1】:

    你的答案确实是例外。

    您正在将EmpleadoRol 保存在该行中

    empleadoRolNew = empleadoRolService.save(empleadoRol);
    

    此实体引用具有此属性的Empleado 类型的实体:

    @NotNull(message="no puede estar vacio!")
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="empleado_Id")
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    private Empleado empleado;
    

    并且该实体是瞬态的,即它没有附加到持久性上下文。

    您可以通过将cascade 属性添加到@ManyToOne 来解决此问题,如问题https://stackoverflow.com/a/13027444/66686 中所述

    或者,您需要先保存Empleado

    我更喜欢第二种变体,因为如果应用领域驱动设计的模式,那么两者是单独的聚合,因此应该由单独的存储库处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-28
      • 2021-08-28
      • 2019-10-19
      相关资源
      最近更新 更多