Spring Boot StackOverFlowError : Null



I have a problem when I want save repository by foreach loop . By Foreach loop user come and save it to another entity

User.class

public class Attendance {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String status;

@ManyToOne(cascade = {CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH,CascadeType.DETACH})
@JoinColumn(name="user_id", nullable=false)
private User user;

}

User.class This is user class of User Entity

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String username;

@OneToMany(mappedBy = "user",cascade = CascadeType.ALL)
@JsonIgnore
private List<Attendance> attendances;

Error show :: java.lang.StackOverflowError: null

@Scheduled(initialDelay = 10000,fixedDelay = 30000)
public void insertHolidaysAttendance() throws Exception {

    Calendar c1 = Calendar.getInstance();

    if ((c1.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY)  || (c1.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY)) {

        List<User> userList = userService.fetchUserList();

        List<Attendance> attendanceList = new ArrayList<>();

        for (User user: userList){
            Attendance attendance = new Attendance();

            System.out.println("Curent user "+user);
            attendance.setStatus("WEEKEND");
            attendance.setUser(user);
            attendanceList.add(attendance);
        }

        System.out.println("Attendance List "+attendanceList+"n");

         attendanceRepository.saveAll(attendanceList);
         userList.clear();
         attendanceList.clear();

    } else {
        System.out.println("Today is working Day");

    }

}

Answer

Mixing what I saw in your code and what you said in comments I found the guilty.

  • the trigger line : System.out.println("Attendance List "+attendanceList+"n");
  • the cause : @Data

This annotation will add a toString implementation on your objects and by default it prints all the non static fields… causing infinite cyclic calls because attendance tries to print user then user tries to print attendance and again attendance tries to print user… you’re looping forever.

Either add the annotation @ToString.Exclude on one of the 2 relationships or re-write toString implementation by yourself.

Always take care on code generation frameworks like Lombok. It could give you some nasty surprises 😉



Source: stackoverflow