【问题标题】:JPA generate fails with JSONJPA 生成失败并显示 JSON
【发布时间】:2017-07-30 03:01:23
【问题描述】:

我找不到任何解决方案来解决这个问题,所以我决定创建一个新问题。我有一个简单的类

@Entity
public class Reservation {

// private Integer RESERVATION_ID;
// private Integer id;
private long code;
private Date date;
private Client reservationClient;
private WashType reservationWashType;
private Vehicle reservationVehicle;
private Wash reservationWash;
private Worker reservationWorkerPesel;
private Review reservationReview;
private ReservationReminder reservationReminder;
 }

我在哪里运行这样的查询:

  @Query("SELECT r FROM Reservation r JOIN FETCH r.reservationReminder where r.reservationWorkerPesel = :worker")
List<Reservation> findByReservationWorkerPesel(@Param("worker") Worker worker);

起初我看起来一切都很好,但后来我做了一些类似的操作:

    public List<ReservationReminder> findByReservationWorkerPesel(Worker worker) {
    List<ReservationReminder> reservationReminderList = new ArrayList<>();
    List<Reservation> byReservationWorkerPesel = reservationDao.findByReservationWorkerPesel(worker);
    for (Reservation r : byReservationWorkerPesel) {
        if (r.getReservationReminder() != null && r.getReservationReminder().getChecked() == false)
            reservationReminderList.add(r.getReservationReminder());
    }
    return reservationReminderList;
}

然后,当我看到 JSON 的样子时——这很奇怪,因为:

[{"reservationReminderId":2,"reservation":{"code":263022,"date":1487851200000,"reservationClient":{"clientPesel":"91122619197","name":"Client 1", "surname":"Client 1","email":"client@wp.pl","phone":"234567890","accountNumber":"34567897654345678987654356","clientUser":{"userId":3,"login ":"client","passwordHash":"$2a$10$0jJMMzeh2CTRagk3hwRSlurx.mxLgR1aAUQOYBD9QFqbISeoTSVN。","userRole":{"roleId":3,"name":"CLIENT","users":[{"userId": 8,"login":"clien5","passwordHash":"$2a$10$6WrmwpwOdhv6UXBo2mYq8ucKiQTwvIwTHw23myo6.oujflh8pqKR.","userRole":{"roleId":3,"name":"CLIENT","users":[{ "userId":8,"login":"clien5","passwordHash":"$2a$10$6WrmwpwOdhv6UXBo2mYq8ucKiQTwvIwTHw23myo6.oujflh8pqKR.","userRole":{"roleId":3,"name":"CLIENT","users ":[{"userId":8,"login":"clien5","passwordHash":"$2a$10$6WrmwpwOdhv6UXBo2mYq8ucKiQTwvIwTHw23myo6.oujflh8pqKR.","userRole":{"roleId":3,"name":"CLIENT ","users":[{"userId":8,"login":"clien5","passwordHash":"$2a$10$6WrmwpwOdhv6UXBo2mYq8ucKiQTwvIwTHw23myo6.oujflh8pqKR.","us erRole":{"roleId":3,"name":"CLIENT","users":

....

[{"userId":8,"login":"clien5","passwordHash":"$2a$10$6WrmwpwOdhv6UXBo2mYq8ucKiQTwvIwTHw23myo6.oujflh8pqKR.","userRole":{"roleId":3,"name":" CLIENT","users":[{"userId":8,"login":"clien5","passwordHash":"$2a$10$6WrmwpwOdhv6UXBo2mYq8ucKiQTwvIwTHw23myo6.oujflh8pqKR.","userRole":{"roleId":3," name":"CLIENT","users":[{"userId":8,"login":"clien5","passwordHash":"$2a$10$6WrmwpwOdhv6UXBo2mYq8ucKiQTwvIwTHw23myo6.oujflh8pqKR.","userRole":{"roleId" :3,"name":"CLIENT","users":[{"userId":8,"login":"clien5","passwordHash":{"timestamp":1489015140465,"status":200,"error ":"OK","exception":"org.springframework.http.converter.HttpMessageNotWritableException","message":"无法写入内容:无限递归(StackOverflowError)(通过引用链:com.carwash.domains.User[ \"userRole\"]->com.carwash.domains.Role[\"users\"]->org.hibernate.collection.internal.PersistentBag[0]->com.carwash.domains.User[\"userRole\ "]->com.carwash.domains.Role[\"users\"]->org.hibernate.collection.internal.PersistentB ag[0]->com.carwash.domains.User[\"userRole\"]->com.carwash.domains.Role[\"users\"]->org.hibernate.collection.internal.PersistentBag[0] ->com.carwash.domains.User[\"userRole\"]->com.carwash.domains.Role[\"users\"]->org.hibernate.collection.internal.PersistentBag[0]->com. carwash.domains.User[\"userRole\"]->com.carwash.domains.Role[\"users\"]->org.hibernate.collection.internal.PersistentBag[0]->com.carwash.domains。用户[\"userRole\"]->com.carwash.domains.Role[\"users\"]->org.hibernate.collection.internal.PersistentBag[0]->com.carwash.domains.User[\" userRole\"]->com.carwash.domains.Role[\"users\"]->org.hibernate.collection.internal.PersistentBag[0]->com.carwash.domains.User[\"userRole\"] ->com.carwash.domains.Role[\"users\"]->org.hibernate.collection.internal.PersistentBag[0]->com.carwash.domains.User[\"userRole\"]->com. carwash.domains.Role[\"users\"]->org.hibernate.collection.internal.PersistentBag[0]->com.carwash.domains.User[\"userRole\"]->com.carwash.domains。角色[\"用户\"]-

...

\"]->org.hibernate.collection.internal.PersistentBag[0]->com.carwash.domains.User[\"userRole\"]->com.carwash.domains.Role[\"users\ "]->org.hibernate.collection.internal.PersistentBag[0]->com.carwash.domains.User[\"userRole\"]->com.carwash.domains.Role[\"users\"]-> org.hibernate.collection.internal.PersistentBag[0]->com.carwash.domains.User[\"userRole\"]->com.carwash.domains.Role[\"users\"]->org.hibernate。 collection.internal.PersistentBag[0]->com.carwash.domains.User[\"userRole\"]->com.carwash.domains.Role[\"users\"]->org.hibernate.collection.internal。 PersistentBag[0]->com.carwash.domains.User[\"userRole\"]->com.carwash.domains.Role[\"users\"]->org.hibernate.collection.internal.PersistentBag[0] ->com.carwash.domains.User[\"userRole\"])","path":"/api/reservationreminder"}

我做错了什么?

也许它可以告诉你一些事情 - 我不知道为什么在制作了一个 GET 方法(仅获取)之后我得到了一些错误?

【问题讨论】:

    标签: json jpa repository spring-data-jpa


    【解决方案1】:

    UserUserRole 对象之间有一个 Infinite recursion。每当用户被序列化时,他的相关用户角色也会被序列化。由于用户角色也确实与用户有关系,因此您具有递归。

    对此的解决方案可能是使用@JsonManagedReference(添加到User 中的关系)和@JsonBackReference(在UserRoles 中的realtion)。也可以在这里查看:Infinite Recursion with Jackson JSON and Hibernate JPA issue

    @Entity
    public class User
       ...
       @JsonManagedReference
       private Set<UserRole> userRoles;
    
    
    @Entity
    public class UserRole
       ...
       @JsonBackReference
       private User user;
    

    @JsonManagedReference 意味着在序列化过程中会考虑到关系部分。所以相关的用户角色也会被序列化。由于那里的相关连接标有@JsonBackReference 序列化停止进一步。

    【讨论】:

    • 我刚刚意识到问题出在哪里,但是我不知道如何使用@JsonBackReference@JsonManagedReference@JsonBackReference 应该放在哪个站点上,@JsonManagedReference 应该放在哪个站点上?
    • 好的,但是为什么你使用@JsonManagedReference private Set&lt;UserRole&gt; userRoles;而不是@JsonBackReference private Set&lt;UserRole&gt; userRoles;
    • 再次编辑 ;).. 我无法更好地解释它。另请查看我链接的其他问题。有人也描述了它(也许更好)。
    • 好的,我明白了。下面我问了与这些注释相关的问题,你能帮我吗?
    • 也许应该添加一个真正的新问题。这里有点混乱。
    【解决方案2】:

    @KLHauser

    如果我有课,如何管理这个案例

    @Entity
    public class ReservationReminder {
    private int reservationReminderId;
    private Reservation reservation;
    private boolean isChecked;
    private Date checkedDate;
    

    和预订类

    @Entity
    public class Reservation {
    
    // private Integer RESERVATION_ID;
    // private Integer id;
    private long code;
    private Date date;
    private Client reservationClient;
    private WashType reservationWashType;
    private Vehicle reservationVehicle;
    private Wash reservationWash;
    private Worker reservationWorkerPesel;
    private Review reservationReview;
    private ReservationReminder reservationReminder;
    
    @Entity
    public class Worker {
    
    private String workerPesel;
    private String name;
    private String surname;
    private Date startDateWorking;
    private String accountNumber;
    private List<Review> workerReview;
    private Adress workerAdress;
    private List<LaborHistory> workerLaborHistory;
    private Wash workerWash;
    //private List<WorkerWorkerTime> workerWorkTime;
    // private Role WORKER_ROLE;
    private User workerUser;
    private List<Reservation> workerReservation;
    

    我想用 Reservation 类的 Worker 加载 ReservationReminder 类?如果我像这样使用@JsonIgonre

    @OneToOne(mappedBy = "reservationReminder", fetch = FetchType.LAZY)
    @JsonIgnore
    public Reservation getReservation() {
        return reservation;
    }
    

    我只从 ReservationReminder 得到了一个带有 checkDate、isChecked 和 reservationReminderId 的 Json

    【讨论】:

    • 如果你想将 ReservationReminder 对象与 Reservation 及其 Worker 一起加载,那么你不应该在任何对应关系上使用@JsonIgnore。这意味着在生成 Json 时将忽略该关系。
    • 也尝试使用@JsonManagedReference@JsonBackReference ,但不起作用
    • 首先,您需要将这些注释添加到UserUserRole,如我的回答中所述。然后,如果那里的无限递归是固定的,我们再往下看。遵循那里的关系的序列化路径看起来像 ReservationReminder -> Reservation -> Worker -> User -> UserRole
    • 我修复了递归。我们可以创建一个聊天广告在那里进一步讨论吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-14
    • 2015-12-31
    • 1970-01-01
    • 2021-12-10
    • 2020-02-08
    • 2011-05-21
    相关资源
    最近更新 更多