javaspringspring-bootjpa

Stackoverflow when evaluate expression intellij with JPA Spring Boot


I asked today a question, i created a user model.

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "_user")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class User implements UserDetails {

  @Id
  @GeneratedValue
  private Integer id;
  private String firstname;
  private String lastname;
  @NotNull
  @Column(unique=true)
  private String email;
  @NotNull
  @Column(unique=true)
  private String usrname;

  @NotNull
  @ColumnDefault("'img/avatar1.jpg'")
  private String avatar;

  @JsonIgnore
  private String password;

  @Enumerated(EnumType.STRING)
  private Role role;

  @JsonIgnore
  @OneToMany(mappedBy = "user")
  private List<Token> tokens;

In my service, i'd like to get the result when i evaluate method :

User updateUser = userRepository.getById(userId)
                .orElseThrow(() -> new ResourceNotFoundException("L'utilisateur n'existe pas avec l'id: " + userId));

Here is my getById(userId)

@Query(value = "SELECT * FROM _user u where u.id = :id", nativeQuery = true)
  Optional<User> getById(int id);

When i evaluate method to get result, i got this :

enter image description here

But there is no problems, because my code continue executing .. Strange things, in console, i haven't StackOverflow issues..

I want to enter in debug mode and evaluate result because i got a ERROR [https-jsse-nio-443-exec-3] c.d.x.ExceptionHandler: Could not commit JPA transaction error.


EDIT

Add the fullstacktrace and my userId is int(1) not a String.

enter image description here

enter image description here

I hope someone had this bug and solved it.


Solution

  • The root cause is probably this lombok issue since toString() method is by default invoked from console debugger and it fails because of infinitive recursion which is then causing the StackOverflowError.

    The root cause for this in your specific example is the

    public class User implements UserDetails {
          ....
    
          @JsonIgnore
          @OneToMany(mappedBy = "user")
          private List<Token> tokens;
          }
    

    One workaround to solve this issue would be to exclude the field from toString() that contains references back to the original object which causes infinite recursion. Somewhere in your Token.class there should be a field:

    @ManyToOne 
    private User user;
    

    You can use there the lombok annotation @ToString.Exclude as

    @ManyToOne 
    @ToString.Exclude
    private User user;
    

    Now toString() method provided from lombok for User.class will be able to print the list from Token.class without causing infinite recursion since the reference back to the original object will not be considered in that objects toString().