programing

Lombok - java.lang.StackOverflowError: toString 메서드의 null입니다.

golfzon 2023. 4. 4. 22:37
반응형

Lombok - java.lang.StackOverflowError: toString 메서드의 null입니다.

나는 수업이 두 개 있다.Product그리고.Categorie카테고리 내 제품 목록을 수정하고 싶을 때categoryRepository.save(c1)다음 코드와 같이 다음 오류가 발생합니다.

 java.lang.StackOverflowError: null
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:449) ~[na:1.8.0_191]
        at java.lang.StringBuilder.append(StringBuilder.java:136) ~[na:1.8.0_191]
        at org.sid.entities.Product.toString(Product.java:12) ~[classes/:na]
        at java.lang.String.valueOf(String.java:2994) ~[na:1.8.0_191]
        at java.lang.StringBuilder.append(StringBuilder.java:131) ~[na:1.8.0_191]
        at java.util.AbstractCollection.toString(AbstractCollection.java:462) ~[na:1.8.0_191]
        at java.lang.String.valueOf(String.java:2994) ~[na:1.8.0_191]
        at java.lang.StringBuilder.append(StringBuilder.java:131) ~[na:1.8.0_191]
        at org.sid.entities.Categorie.toString(Categorie.java:15) ~[classes/:na]
        at java.lang.String.valueOf(String.java:2994) ~[na:1.8.0_191]

@Document
@Data @AllArgsConstructor @NoArgsConstructor @ToString
public class Categorie {
    @Id
    private String id;
    private String name;
    @DBRef
    @JsonIgnore
    private Collection<Product> products=new ArrayList<>();

@Document
@Data @AllArgsConstructor @NoArgsConstructor @ToString
public class Product {
    @Id
    private String id;
    private String name;
    private double price;
    @DBRef
    private Categorie categorie;

@Bean
    CommandLineRunner start(CategoryRepository categoryRepository, ProductRepository productRepository){

        return args -> {
            categoryRepository.deleteAll();
            Stream.of("c1 Ordinateur","c2 Imprimente").forEach(c->{
                categoryRepository.save(new Categorie(c.split(" ")[0],c.split(" ")[1],new ArrayList<>()));
            });
            categoryRepository.findAll().forEach(System.out::println);

            productRepository.deleteAll();
            Categorie c1=categoryRepository.findById("c1").get();
            Stream.of("P1","P2","P3","P4").forEach(name->{
               Product p= productRepository.save(new Product(null,name,Math.random()*1000,c1));
               c1.getProducts().add(p);
               categoryRepository.save(c1);
            });

productRepository.findAll().forEach(p->{
                System.out.println(p.toString());
            });

        };
    }

이 문제를 해결할 수 있는 아이디어를 가진 사람이 있나요?감사해요.

에 순환 참조가 있습니다.toStringLombok에서 생성한 메서드입니다.

  • Product참조하고 있다CategorietoString, 이것은 참조하고 있다.Product, 등

exclude 속성을 사용할 수 있습니다.@ToString단, 곧 폐지될 예정입니다.따라서@ToString.Exclude:

@Document
@Data @AllArgsConstructor @NoArgsConstructor @ToString
public class Product {
  ...

  @ToString.Exclude
  private Categorie categorie;

  ...
}

@Document
@Data @AllArgsConstructor @NoArgsConstructor @ToString
public class Categorie {
  ...

  @ToString.Exclude
  private Collection<Product> products=new ArrayList<>();

  ...
}

롬복 여기랑 여기랑

제 생각엔@ToString주석은 모든 필드의 값을 인쇄하는 toString 메서드를 생성하기 위해 사용하는 도구(Lombok?)에 대해 알려줍니다.각 클래스는 다른 클래스를 참조합니다.제품에는 카테고리가 있고 카테고리에는 제품 인스턴스 목록이 있습니다.따라서 toString 구현은 Category를 인쇄할 때 각 제품의 toString을 호출하고 Category 등의 toString을 호출합니다.Product는 제품 목록에 해당 제품을 포함하는 Category를 참조할 가능성이 높기 때문에 toString 콜은 스택이 오버플로될 때까지 앞뒤로 바꿉니다.해결책은 ToString 메서드에서 Categoryie, products 또는 Product.category 중 하나를 인쇄하지 않는 것입니다.Lombok을 사용하는 경우 Category.products에 주석을 달아 보겠습니다.@ToString.Exclude.

저는 Spring JPA 구현과 관련하여 비슷한 문제가 있었습니다.또한 엔티티는 @ToString, @EqualsAndHashCode, @Getter / @Setter 및 @RequiredArgsConstructor를 함께 생성하는 Lombok @Data로 주석을 달았습니다.단, @ToString, @EqualsAndHashCode 주석에서는 보통 다른 엔티티 및 다른 One-to-One 관계 엔티티를 참조하는 컬렉션을 포함하여 엔티티의 모든 속성을 가진 코드가 생성됩니다.이로 인해 순환 참조가 발생하고 Lazy 컬렉션도 로드됩니다(기본적으로 1 대 다 및 다 로드는 Lazy 방식으로 로드됩니다).

추가 중@ToString.Exclude또는@EqualsAndHashCode.Exclude번거로운 코드가 생성되므로 JPA 엔티티에서는 @Data 또는 @ToString, @EqualsAndHashCode 사용을 피하는 것이 좋습니다.사용하기 전에 IDE를 사용하여 toString, equals, hashCode를 생성하고 이를 검증하는 것이 좋습니다(non-null vs null 필드 등).

언급URL : https://stackoverflow.com/questions/54653734/lombok-java-lang-stackoverflowerror-null-on-tostring-method

반응형