如何使用Thymeleaf在JavaScript中访问具有一组另一个对象的Sping Boot POJO

amrnrhlw  于 2023-03-28  发布在  Java
关注(0)|答案(1)|浏览(118)

我有一个对象Schools和另一个对象Students。Schools与Students有OneToMany关系,这样一个School就可以有一组多个Students。我试图使用Javascript和Thymeleaf从控制器访问提供给页面的Schools列表。当我尝试这样做时,我在控制台中得到一个错误,提到:

at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.3.jar:2.13.3]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.3.jar:2.13.3]
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.13.3.jar:2.13.3]
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.13.3.jar:2.13.3]
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.13.3.jar:2.13.3]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.13.3.jar:2.13.3]

我已经确定这个错误只发生在我试图通过Javascript Thymeleaf访问对象时。如果我在html中使用Thymeleaf访问对象,它会完全按照它应该的方式加载数据。
以下是我的学校对象:

@Entity
public class Schools {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @NonNull
    private String schoolName;
    @NonNull
    private String type; 
    @NonNull
    private String schoolGrade; 
    @NonNull
    private int studentCount; 
    @NonNull
    private int startHour; 
    @NonNull 
    private int startMin; 
    @NonNull 
    private String startAmPm; 
    @NonNull 
    private int endHour; 
    @NonNull
    private int endMin; 
    @NonNull
    private String endAmPm;
    @NonNull
    private Date startDate; 
    @NonNull
    private Date endDate; 
    @NonNull
    private int schoolDays;
    @NonNull
    private String address;
    @NonNull
    private String city;
    @NonNull
    private String state;
    @NonNull
    private int zip;
    @NonNull
    private String phone;
    @NonNull
    private boolean isActive;
    
    //one-to-one relationship so each location point is associated with one school
    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "location_id", referencedColumnName = "location_id")
    private LocationPoint location;
    
    //mapping students one to many from schools
    //@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval=true)
    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.REMOVE, CascadeType.REFRESH, CascadeType.DETACH}, orphanRemoval=true)
    @JoinColumn(name = "school_id")
    private Set<Students> students = new HashSet<>();

下面是我的学生对象:

@Entity
public class Students {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int studentId;
    @NonNull private int studId;
    @NonNull private boolean graduated;
    @NonNull private String firstName;
    @NonNull private String midName;
    @NonNull private String lastName;
    @NonNull private String suffix;
    @NonNull private float grade;
    @NonNull private String address1;
    @Column(columnDefinition = "TEXT")
    @NonNull private String address2;
    @NonNull private String city;
    @NonNull private String state;
    @NonNull private int zipCode;
    @NonNull private String gender; 
    @NonNull private Date birthDate; 
    @NonNull private String phoneNum;
    @NonNull private String cellPhoneNum;    
    @NonNull private String emergencyPhoneNum;
    @NonNull private String parentName;
    @NonNull private String schoolName;
    @NonNull private Date enter;
    @NonNull private boolean isEnter;
    @NonNull private Date Withdrawl;
    @NonNull private boolean isWithdrawl;
    @NonNull private boolean hazardousRoad;
    @NonNull private String travelMode;
    @NonNull private String driverNote;
    @NonNull private String misc;
    @NonNull private String journal;
    @NonNull private String medical;
    @NonNull private boolean isCustody;
    @Column(columnDefinition = "TEXT") private String alt1Name;
    @Column(columnDefinition = "TEXT") private String alt1Relationship;
    @Column(columnDefinition = "TEXT") private String alt1Address1;
    @Column(columnDefinition = "TEXT") private String alt1Address2;
    @Column(columnDefinition = "TEXT") private String alt1City;
    @Column(columnDefinition = "TEXT") private String alt1State;
    @Column(columnDefinition = "TEXT") private long alt1ZipCode;
    @Column(columnDefinition = "TEXT") private String alt1Phone;
    @Column(columnDefinition = "TEXT") private String alt1CellPhone;
    @Column(columnDefinition = "TEXT") private String alt2Name;
    @Column(columnDefinition = "TEXT") private String alt2Relationship;
    @Column(columnDefinition = "TEXT") private String alt2Address1;
    @Column(columnDefinition = "TEXT") private String alt2Address2;
    @Column(columnDefinition = "TEXT") private String alt2City;
    @Column(columnDefinition = "TEXT") private String alt2State;
    @Column(columnDefinition = "TEXT") private long alt2ZipCode;
    @Column(columnDefinition = "TEXT") private String alt2Phone;
    @Column(columnDefinition = "TEXT") private String alt2CellPhone;
    @Column(columnDefinition = "TEXT") private String alt3Name;
    @Column(columnDefinition = "TEXT") private String alt3Relationship;
    @Column(columnDefinition = "TEXT") private String alt3Address1;
    @Column(columnDefinition = "TEXT") private String alt3Address2;
    @Column(columnDefinition = "TEXT") private String alt3City;
    @Column(columnDefinition = "TEXT") private String alt3State;
    @Column(columnDefinition = "TEXT") private long alt3ZipCode;
    @Column(columnDefinition = "TEXT") private String alt3Phone;
    @Column(columnDefinition = "TEXT") private String alt3CellPhone;
    @NonNull private String studentType1;
    @NonNull private String studentType2;
    @NonNull private String studentType3;
    @NonNull private String pickUpLocation;
    @NonNull private int pickUpStopNo;
    @NonNull private String busRoute1;
    @NonNull private String pickUpTime;
    @NonNull private String deliveryLocation;
    @NonNull private int deliveryStopNo;
    @NonNull private String busRoute2;
    @NonNull private String deliveryTime;
   
    //many-to-one relationship so multiple students are associated with one school
    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private Schools school;
    
    //many-to-one relationship so multiple students are associated with one pickupDropoff
    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private PickupDropoff2 pickupDropoff;

    //one-to-one mapping so each student is associated with one location point
    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private LocationPoint location;

这是我的控制器:

//create pickupDropoff point display page
    @RequestMapping({"/createPickupDropoff"})
    public String createPickupDropoff(PickupDropoff2 pickupDropoff, Model model) {
        
        model.addAttribute("schools", schoolRepo.findAll());
        model.addAttribute("students", studentRepo.findAll());
        
        return "create-pickupDropoff-point";
    }

下面是我的JavaScript:

<script type="text/javascript" th:inline="javascript">
  var schools = /*[[${schools}]]*/ 'false';
</script>
dphi5xsq

dphi5xsq1#

我发现问题出在School和Students的双向关系上。这导致了一个递归循环,使数据无法在JSON对象中序列化。我通过添加以下内容修复了这个问题:

@JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "studentId")

然后呢

@JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")

这导致两个域仅加载1级深度,并停止递归循环。

相关问题