JPA | 양방향 무한 루프

DoItDev·2021년 8월 8일
0
post-thumbnail

에러의 원인

JPA 를 @ManyToMany를 사용을 하다 보면 인피니티 루프가 발생을 한다.
근데 무작정 발생을 하는 것은 아니고 양뱡향성 매핑을 할때 발생을 한다.
@OneToMany, @ManyToOne 등 ... 어노테이션 매핑을 할때 발생이 된다.

스크린샷 2021-08-08 오후 9 57 24 스크린샷 2021-08-08 오후 9 56 48
java.lang.StackOverflowError: null
	at java.base/java.time.temporal.ValueRange.isValidIntValue(ValueRange.java:295) ~[na:na]
	at java.base/java.time.temporal.ValueRange.checkValidIntValue(ValueRange.java:329) ~[na:na]
	at java.base/java.time.temporal.ChronoField.checkValidIntValue(ChronoField.java:736) ~[na:na]
	at java.base/java.time.LocalDate.ofEpochDay(LocalDate.java:369) ~[na:na]
	at java.base/java.time.LocalDateTime.ofEpochSecond(LocalDateTime.java:422) ~[na:na]
	at java.base/java.time.format.DateTimeFormatterBuilder$InstantPrinterParser.format(DateTimeFormatterBuilder.java:3418) ~[na:na]
	at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2345) ~[na:na]
	at java.base/java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1846) ~[na:na]
	at java.base/java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1820) ~[na:na]
	at java.base/java.time.Instant.toString(Instant.java:1329) ~[na:na]
	at com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializerBase.serialize(InstantSerializerBase.java:106) ~[jackson-datatype-jsr310-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializerBase.serialize(InstantSerializerBase.java:40) ~[jackson-datatype-jsr310-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755) ~[jackson-databind-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755) ~[jackson-databind-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.11.3.jar:2.11.3]
	at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2

해결방법

주로 DTO 를 바꾸어서 받거나 json 직렬화에서 속성을 없에 버린다.
@JsonIdentityInfo 이번에는 이 어노테이션을 사용해서 해결을 해보려고 한다.
주의 jackson 2.0 이상 부터 사용이 가능하다.

@Data
@Table(name = "app_group")
@Entity
@NoArgsConstructor
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "id")
public class Group extends AppBaseEntity implements Serializable {

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

    @Column(name = "group_title", nullable = false)
    private String title;

    @Column(name = "use_yn" , nullable = false)
    private Boolean useYn;

    @ManyToMany(mappedBy = "groups")
    private Set<User> users = new HashSet<>();

    @PrePersist
    public void onPrePersist(){
        if(BooleanUtils.isNotTrue(this.useYn)){
            this.useYn = Boolean.FALSE;
        }
    }
}

ObjectIdGenerators.class 를 어노테이션에 상속을 받아서 사용을 한다.
IntSequenceGenerator => id 값이 number
StringIdGenerator=> id 값이 UUID 형태일때 사용을 하면된다.

profile
Back-End Engineer

0개의 댓글