【问题标题】:Saving an entity with a nested object with Crud repo使用 Crud 存储库保存具有嵌套对象的实体
【发布时间】:2021-05-16 01:20:50
【问题描述】:

如何保存一个嵌套了另一个实体的实体?

回购

public interface ReservationRepository extends JpaRepository<Reservation, Integer> {
    Optional<Reservation> findReservationBySection_SectionId(int id);
}

服务



@Service
public class ReservationService {
    private final Logger logger = LoggerFactory.getLogger(getClass().getName());
    @Autowired
    private ReservationRepository reservationRepository;
    @Autowired
    private SectionRepository sectionRepository;
    @Autowired
    private UserRepository userRepository;


    public Reservation addReservation(Reservation reservation) {
        Reservation newReservation = new Reservation();
        newReservation.setCount(reservation.getCount());
        newReservation.setCustom_section_name(reservation.getCustom_section_name());
        newReservation.setFrom_time(reservation.getFrom_time());
        newReservation.setTo_time(reservation.getTo_time());
        newReservation.setSection(sectionRepository.getOne(reservation.getSection().getSectionId()));
        newReservation.setUser(userRepository.getOne(reservation.getUser().getUserId()));
        logger.info(newReservation.toString());
        return reservationRepository.save(newReservation);
    }

}

用户实体

User
    @Id
    @GeneratedValue
    @Column(name = "user_id")
    private int userId;

    @Column(name = "name")
    private String name;
    
    @Column(name="email", unique = true)
    private String email;

    @JsonIgnore
    @Column(name = "password")
    private String password;

    @Column(name = "phone")
    private String phone;

    @Column(name = "expiration_date")
    private Timestamp expirationDate;

部分实体

Section
    @Id
    @GeneratedValue
    @Column(name = "section_id")
    private int sectionId;

    @Column(name = "section_name")
    private String sectionName;

    @OneToOne
    @JoinColumn(name="room_id")
    private Section roomId;

预订实体

    @Id
    @GeneratedValue
    @Column(name = "reservation_id")
    private int reservationId;

    @ManyToOne
    @MapsId("section_id")
    @JoinColumn(name = "section_id")
    private Section section;

    @ManyToOne
    @MapsId("user_id")
    @JoinColumn(name = "user_id")
    private User user;

    @Column(name = "count")
    private int count;

    @Column(name = "custom_section_name")
    private String custom_section_name;

    @Column(name = "from_time")
    private Timestamp from_time;


    @Column(name = "to_time", unique = true)
    private Timestamp to_time;

预期结果:

想要在数据库中保存包含部分和用户的预订。像这样:

实际结果:

已创建预订但缺少 section_id 和 user_id

SQL 数据库表的 section_id 和 user_id 不为空,因为它们的表中有主键。 如果需要,将提供更多信息。

【问题讨论】:

    标签: spring spring-boot jpa spring-data-jpa crud


    【解决方案1】:

    如果 Reservation 拥有与 Section 的关系,则需要将 Cascade 添加到关系中。当您持久化 Reservation 时,Hibernate 会拦截您还想持久化一个 Section 并将其对应的引用附加到 Reservation 实体的事实。

    你可以添加

        @ManyToOne(cascade = CascadeType.ALL)
        @JoinColumn(name = "section_id")
        private Section section;
    

    您可以根据需要修改Cascade类型(例如:如果您不想级联删除操作)

    这是一篇好文章: https://www.baeldung.com/jpa-cascade-types

    【讨论】:

    • 您好,感谢您抽出宝贵时间回答。然而,这并没有解决问题,但我了解到与预订进行级联是一件聪明的事情。为了清楚起见:我从端点获得了一个要保存在数据库中的 Reservation 对象,但这是不允许的,因为我在发送到预留的数据中有一个部分和用户对象。因此,我试图找出谁可以通过参考某个部分和一个用户来保存预订。
    • 您还可以尝试另一种技巧。在 @JoinColumn 中为 Section 和 User 实体添加 nullable = false@JoinColumn(name = "section_id", nullable = false) @JoinColumn(name = "user_id", nullable = false)
    • 仍然将“字段 'section_id' 没有默认值”作为问题。 Mabye这与它有关吗?很难弄清楚,但似乎实体引用没有与新的 Reservation 一起保存。
    • 你能不能也把@MapsId去掉,在那里没有意义。
    • 似乎修复了它。谢谢!
    猜你喜欢
    • 2021-05-14
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 2023-03-31
    • 2017-06-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    相关资源
    最近更新 更多