【问题标题】:Spring data JPA updates one/many-to-many relationship using Beanutils.copyPropertiesSpring data JPA 使用 Beanutils.copyProperties 更新一对多关系
【发布时间】:2018-10-23 20:18:07
【问题描述】:

我有两个具有一对多关系的类。

class Hotel {
    private String name;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Meeting> meetings = new ArrayList<>();
}
class Meeting {
    @Column(name = "meeting_time")
    @NotNull
    private LocalDateTime meetingTime;

    @Column(name = "number_people")
    @NotNull
    @Min(1)
    private int numberPeople;
}

class HotelDto{
    private long id;
    private List<MeetingDto> meetingDtos;
}
class MeetingDto {
    private long id;
    private LocalDateTime meetingTime;
    private int numberPeople;
}

要更新数据库中的现有酒店,我是否必须从会议数据库表中逐一检索现有会议并分配新的时间和号码,然后将会议列表分配给酒店?如果不是,我通过BeanUtils.copyProperties复制列表后如何解决引用异常 例如

Hotel newHotel = new Hotel();
Hotel hotel = hotelDao.findById(hotelDto.getId());
List<Meeting> newMeetingList = new ArrayList<>();
for (MeetingDto mDto : hotelDto.getMeetingDtos()) {
    Meeting meeting = meetingDao.findById(mDto.getId());
    meeting.setMeetingTime(mDto.getMeetingTime());
    meeting.setNumberPeople(mDto.getNumberPeople());
    // meetingDao.saveAndFlush(meeting);     should I add this?
    newMeetingList.add(meeting);
}
newHotel.setMeetings(newMeetingList);
BeanUtils.copyProperties(newHotel, hotel, "id");
hotelDao.saveAndFlush(hotel);

有没有更好的方法来更新具有关系的对象?

【问题讨论】:

    标签: java spring spring-data-jpa


    【解决方案1】:

    为了更新酒店,你应该从数据库中加载它,更新你想要的并保存它

    Hotel hotel = hotelDao.findById(hotelDto.getId());
    hotel.getMeetings().add(newMeeting); 
    hotelDao.saveAndFlush(hotel);
    

    【讨论】:

    • 看看这个vladmihalcea.com/…
    • 我之前读过,它只添加了'many'部分的项目,我相信它会创建一个新项目而不是更新现有项目。所以新添加的item有不同的id。
    • 酒店和会议有一个 ID 对吗?我假设您没有在此处将其添加到实体中,但它们存在于您的代码中。在您映射它的方式中,使用单向 OneToMany,Hotel 拥有该关系。您只需要加载酒店,从列表中获取要更新的会议并更改它,仅此而已。它不工作吗?顺便说一句,您没有听从他的建议:“当我们确实需要关联父端的集合时,双向 OneToMany 关联是映射一对多数据库关系的最佳方式。”
    • 我试过了,但效果很奇怪:有时我调用setter后数据立即改变,有时只有我通过dao保存项目后才生效。我也想使用BeanUtils.copyProperties 来节省我的时间,但它不适用于收藏。
    【解决方案2】:

    BeanUtils 是一个很好用的 API,但它会进行浅对象映射。在处理包含在其他对象中的对象并弄清楚它们的数据类型时,它做得不好。使用 ModelMapper 而不是 BeanUtils。此外,ModelMapper 使用 TypeTokens 来允许映射泛型参数化类型。如果你想知道它是如何工作的,你可以从这个链接阅读文档http://modelmapper.org/

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 2018-04-14
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    相关资源
    最近更新 更多