❗️jpa에선 프록시, 리플렉션을 위해 기본 생성자가 필요함!!
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
자꾸 500 에러가 났는데 디버깅 해보니까 저기로 들어갔음...
문제는 내가 기본생성자를 정의하지 않았던 것..!
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 원랜 없었음. 그래서 문제가 생김.
public class Diary extends BaseEntity {
...
@Builder(access = AccessLevel.PRIVATE)
public Diary(User user, String title, String content, LocalDate diaryDate, Image image, Comment comment) { // 명시적 생성자가 있어서 spring boot에서 자동으로 기본 생성자 안 만들어줌.
this.user = user;
this.title = title;
this.content = content;
this.diaryDate = diaryDate;
this.image = image;
this.comment = comment;
}
public static Diary create(User user, String title, String content, LocalDate diaryDate) {
return Diary.builder()
.user(user)
.title(title)
.content(content)
.diaryDate(diaryDate)
.build();
}
...
}
원래는 기본생성자 없어도 스프링 부트에서 자동으로 생성해주는데
명시적 생성자가 있는 경우는 자동으로 생성을 안 해준다고 한다.. 내 경우가 그것...
@NoArgsConstructor(access = AccessLevel.PROTECTED)
추가해주니까 해결됨..
엔티티에 생성자 제대로 만들었는지 꼭!!꼭!!!!!!!! 확인하기
프록시는 실제 객체를 대신하는 대리 객체입니다. JPA와 Hibernate에서 주로 다음 목적으로 프록시를 사용합니다:
a) 지연 로딩 (Lazy Loading):
@ManyToOne(fetch = FetchType.LAZY)로 설정된 관계에서 사용됩니다.b) 성능 최적화:
c) 트랜잭션 관리:
리플렉션은 실행 중인 자바 프로그램이 자체적으로 검사하거나 클래스의 내부 속성을 조작할 수 있게 해주는 API입니다. JPA와 Hibernate에서 리플렉션을 사용하는 주요 이유는 다음과 같습니다:
a) 동적 객체 생성:
b) 프로퍼티 접근:
c) 메타데이터 분석:
@Entity, @Column 등의 JPA 어노테이션을 분석하여 매핑 정보를 구성합니다.엔티티 인스턴스화:
Constructor<?> ctor = entityClass.getDeclaredConstructor();
ctor.setAccessible(true);
Object entity = ctor.newInstance();
프로퍼티 설정:
Field field = entityClass.getDeclaredField("id");
field.setAccessible(true);
field.set(entity, 1L);
메서드 호출:
Method method = entityClass.getDeclaredMethod("setName", String.class);
method.setAccessible(true);
method.invoke(entity, "John Doe");
프록시 생성과 리플렉션 사용은 JPA와 Hibernate가 유연하고 강력한 ORM 기능을 제공할 수 있게 해주는 핵심 메커니즘입니다. 그러나 이러한 기능을 사용하려면 기본 생성자가 필요하며, 이는 우리가 엔티티 클래스를 설계할 때 고려해야 할 중요한 점입니다.