JPA(Hibernate)上的多个双向映射问题

Posted

技术标签:

【中文标题】JPA(Hibernate)上的多个双向映射问题【英文标题】:Multiple bidirectional mapping issue on JPA (Hibernate) 【发布时间】:2019-07-04 14:52:24 【问题描述】:

我在搞清楚 JPA OneToMany/ManyToOne 的映射时遇到了问题,最初有人告诉我它与需要位于父实体中的 CascateType.ALL 有关,我确实添加了这一点,但我仍然得到一个“分离实体”错误,我更改了获取类型,现在我得到了一个

Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing :

错误,我完全不知道该怎么做。

我有一个包含 OneToOne 关系和两个 OneToMany 关系的主实体(reserve)。

OneToMany 关系将此作为注释:

@OneToOne(mappedBy = "reserve", fetch = FetchType.EAGER, cascade = CascadeType.ALL)

孩子(例如其中一个)也有两个 ManyTwoOne 关系,注释是:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "idReserve", referencedColumnName = "idReserve")

这里是创建过程(实际的实体名称/属性是西班牙语,我只是在上面翻译了它以便于理解):

Pago pago = new Pago();
        pago.setTipo("Efectivo");
        pago.setTotal(1500);

        Alojamiento alojamiento = new Alojamiento();
        alojamiento.setNombre("Hotel las Flores");
        alojamiento.setNumeroDeHabitaciones(30);
        alojamiento.setTipo("Hotel Turistico");
        alojamiento.setValoracion(5);
        alojamiento.setUbigeo(11);
        alojamiento.setCodAlojamiento("ALO01");

        Habitacion habitacion = new Habitacion();
        habitacion.setDescripcion("Habitación Ejecutiva");
        habitacion.setTipo(3);
        habitacion.setNumero("5");
        habitacion.setPrecio("1500 dolares");
        habitacion.setCodHabitacion("HAB01");

        List<Habitacion> listHab = new ArrayList<>();
        listHab.add(habitacion);
        alojamiento.setHabitaciones(listHab);

        Usuario usuario = new Usuario();
        usuario.setNombres("Jeremy");
        usuario.setApellidos("Tornero");
        usuario.setContrasena("1234");
        usuario.setEmail("jeremy@gmail.com");
        usuario.setFoto("");
        usuario.setCodUsuario("USU01");

        Reserva reserva = new Reserva();
        reserva.setCantidadDePersonas(3);
        reserva.setFechaIngreso(LocalDate.of(19,7,15));
        reserva.setFechaSalida(LocalDate.of(19,10,30));
        reserva.setComentarios("");
        List<Habitacion> listHab2 = new ArrayList<>();
        listHab2.add(habitacion);
        reserva.setHabitaciones(listHab2);
        reserva.setUsuario(usuario);
        List<Pago> listPago = new ArrayList<>();
        listPago.add(pago);
        reserva.setPagos(listPago);

        pago.setReserva(reserva);
        habitacion.setAlojamiento(alojamiento);
        habitacion.setReserva(reserva);
        usuario.setReserva(reserva);

        pagoRepository.save(pago);
        log.info("success saving pago");
        habitacionRepository.save(habitacion);
        log.info("success saving habitacion");
        alojamientoRepository.save(alojamiento);
        log.info("success saving alojamiento");
        usuarioRepository.save(usuario);
        log.info("success saving usuario");
        reservaRepository.save(reserva);
        log.info("success saving reserva");

当需要从存储库调用 save() 方法时(最后),我似乎在调试时遇到了错误。我不完全确定它是由实体映射引起的,我是如何映射、获取、级联的,还是由于我在应用程序中创建它们的方式引起的。

【问题讨论】:

【参考方案1】:

所以,我在几个小时后修复了它,显然问题是我添加它们的顺序,应该首先实例化具有 OneToMany 的类并且不分配任何东西,而不是直接保存它,然后当ManyToOne 类被创建,你为它们分配已经保存的 OneToMany 类,然后 .save 与存储库类一起保存,这样它将为 json/database 正确分配它们的 ID

【讨论】:

以上是关于JPA(Hibernate)上的多个双向映射问题的主要内容,如果未能解决你的问题,请参考以下文章

hibernate/jpa double OneToOne 与一个实体的双向关系

使用连接表将 JPA 双向 @ManyToOne 关系映射到多个表

层次结构中 JPA 实体之间的双向关系

外键中的 JPA / Hibernate OneToOne Null

如何在唯一的映射或非对象 JPA 中返回多个结果

Hibernate双向多对多对象关系模型映射