728x90
반응형
SMALL
문제점
코틀린에서 JPA를 사용중이며 LhJpaRepositoryImpl 클래스에서 LhJpaRepository 인터페이스를 생성자 주입을 통해 사용중이었다.
@Repository
class LhJpaRepositoryImpl(
val lhJpaRepository: LhJpaRepository
): LhRepository {
override fun create(lhNotice: LhNotice) {
lhJpaRepository.save(LhNoticeEntity().fromModel(lhNotice))
}
override fun searchById(id: Long): LhNotice {
val lhNoticeEntity = lhJpaRepository.findById(id).orElseThrow{Exception("test")};
return lhNoticeEntity.toModel();
}
}
interface LhRepository {
fun create(lhNotice: LhNotice)
fun searchById(id: Long): LhNotice
}
interface LhJpaRepository : JpaRepository<LhNoticeEntity, Long>
lhJpaRepositoryImpl 클래스에서 Despite circular references being allowed, the dependency cycle between beans could not be broken. Update your application to remove the dependency cycle. 순환참조 메시지 두두등장..
chatgpt는 어떤 답변을 줄까?
- 코틀린 클래스 초기화 시점: - 코틀린 클래스의 초기화 시점과 JPA 프록시 객체의 생성 시점이 일치하지 않을 수 있습니다. 이로 인해 예상치 못한 순간에 프록시 객체가 초기화되는 경우 문제가 발생할 수 있습니다.
- 프록시와 데이터 클래스 사용: - Kotlin에서 데이터 클래스를 사용하는 경우, equals(), hashCode(), toString() 등이 자동으로 생성됩니다. 이때 프록시 객체와의 상호 작용에서 예상치 못한 결과가 나타날 수 있습니다.
- -Proxy 클래스의 동작 방식: - JPA는 프록시 객체를 사용하여 지연 로딩 등의 기능을 구현합니다. Kotlin의 특성과 JPA 프록시 객체의 동작 방식이 충돌할 수 있습니다.
그래서?
- 초기화 시점 관리: - 프록시 객체의 초기화 시점을 주의 깊게 관리하고, Kotlin 클래스의 초기화 시점과의 충돌을 방지합니다.
lateinit
사용: -lateinit
키워드를 사용하여 초기화를 늦추는 방법을 고려합니다. 하지만 이 경우, non-nullable 프로퍼티에 대한 안전성을 확인해야 합니다.- Nullable 프로퍼티: - Kotlin에서는 기본적으로 모든 프로퍼티가 non-nullable입니다. 그러나 JPA는 대개 nullable을 허용합니다. 이로 인해 프록시 객체에서 nullable 프로퍼티를 다룰 때 문제가 발생할 수 있습니
- DTO 또는 별도의 데이터 클래스 사용: - JPA 엔터티 클래스와는 별도로 데이터 전송 객체(DTO)나 코틀린 데이터 클래스를 사용하여 JPA 프록시와의 상호 작용을 최소화합니다.
- equals(), hashCode(), toString() 오버라이딩: - Kotlin 데이터 클래스에서 자동으로 생성되는 equals(), hashCode(), toString() 등을 적절히 오버라이딩하여 프록시와의 상호 작용을 관리합니다
해결
나는 @Lazy
추가해주어서 lhJpaRepository를 실제 시용시점에 초기화 하기로 하였다.
@Repository
class LhJpaRepositoryImpl(
@Lazy val lhJpaRepository: LhJpaRepository
): LhRepository {
override fun create(lhNotice: LhNotice) {
lhJpaRepository.save(LhNoticeEntity(code = lhNotice.code,
content = lhNotice.content))
}
override fun searchById(id: Long): LhNotice {
val lhNoticeEntity = lhJpaRepository.findById(id).orElseThrow{Exception("test")}
return LhNotice(code = lhNoticeEntity.code,
content = lhNoticeEntity.content)
}
}
728x90
반응형
LIST