有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java灵活地序列化具有双向关系的嵌套JPA实体

我是JavaSpring的新手,我正试图找到一种方法,根据控制器的访问点,在不同的JSON结果中序列化具有双向关系的嵌套JPA实体

关系:

用户-一对多-预订

预订-多对多房间(预订房间)

酒店一对多客房

课程:

用户。java

@Entity @Table(name ="user") @Getter @Setter
public class User {
    @Id
    @SequenceGenerator(name="user_sequence", sequenceName="user_sequence",allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_sequence")
    private Long id;
    private String first_name;
    private String last_name;

    @OneToMany(mappedBy = "user")
    private List<Booking> bookings = new ArrayList<>();
}

酒店。java

@Entity @Table(name="hotel") @Getter @Setter
public class Hotel {

    @Id
    @SequenceGenerator(name="hotel_sequence",sequenceName="hotel_sequence", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hotel_sequence")
    private Long id;

    private String name;

    @OneToMany(mappedBy = "hotel")
    private List<Room> rooms = new ArrayList<>();
    
}

房间。java


@Entity @Table(name ="room") @Getter @Setter
public class Room {

    @Id
    @SequenceGenerator( name="room_sequence",sequenceName="room_sequence",allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "room_sequence")
    private Long id;
    private String type;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="hotel_id", referencedColumnName = "id")
    private Hotel hotel;

    @ManyToMany(mappedBy = "rooms")
    private List<Booking> booking = new ArrayList<>();

}

预订。java

@Entity @Table(name="booking") @Getter @Setter
public class Booking {

    @Id
    @SequenceGenerator(name="booking_sequence",sequenceName="booking_sequence",allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "booking_sequence")
    private Long id;
    private double price;

    private String info;


    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="user_id", referencedColumnName = "id")
    private User user;


    @ManyToMany
    @JoinTable(
            name="booking_rooms",
            joinColumns = @JoinColumn(name = "booking_id"),
            inverseJoinColumns = @JoinColumn(name="room_id")
    )
    private List<Room> rooms = new ArrayList<>();
}

我需要以下JSON结果:

  • 用户的预订(包括预订中的房间)

  • 包括房间的酒店(不包括房间的预订)

  • 房间的预订(包括用户(不包括他的预订))

我已经在这里阅读了杰克逊的文档:https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion

我尝试了大多数方法,但未能成功完成上述所有结果。我曾尝试创建自定义序列化程序,但正如我所说,我对Spring非常陌生,没有找到一种方法来序列化每个场景的实体。它似乎“太嵌套”而无法成功

我唯一的解决方案是为我想要的结果创建DTO类,然后通过在存储库中循环来“收集”数据,但这是一个非常肮脏的解决方案,因为未来我将拥有更多实体的更复杂的关系结构,因此我将拥有很多DTO类

有没有更好的方式处理这些关系

对于这个具体案例,什么是最好的方法


共 (1) 个答案

  1. # 1 楼答案

    鉴于你的案例并不简单,你在分享的文章中提到的解决方案很容易解决,我肯定会选择DTO。为什么?让我列出几个优点:

    • 明确定义要包含在调用方响应中的内容,无需自定义序列化程序、@JsonViews、@JsonIgnore或其他不易理解的技巧
    • 公共模式的重组是可能的,以便更好地满足客户的需求。这种结构可能与更好地建模业务逻辑的结构不同
    • 内部模型与API消费者知道的公共模型分离,这使得重新设计内部模型并保持相同的公共模型成为可能

    然而,也有一些缺点,比如必须另外将实体映射到DTO。可以通过使用MapStruct等映射库来解决这个问题。然而,优点明显大于缺点,因此您肯定应该使用DTO