PersesTitan(페르) 기술블로그

[Spring] could not initialize proxy - no Session 해결하기 본문

Error

[Spring] could not initialize proxy - no Session 해결하기

PersesTitan(페르) 2023. 1. 10. 01:17

문제

스프링을 사용하면서 아래와 같은 에러가 발생하였는데 처음에는 매핑을 잘못했나싶어서 연관 OneToMany, ManyToOne, JoinColum를 미친듯이 건드리다가 에러 위치를 찍어보니 연관 관계 편의 메소드 부분에서 에러 위치가 잡히더군요.

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.shabi.problemspring.domain.member.Member.problems: could not initialize proxy - no Session
	at org.hibernate.collection.spi.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:631) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
	at org.hibernate.collection.spi.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
	at org.hibernate.collection.spi.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:611) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
	at org.hibernate.collection.spi.AbstractPersistentCollection.write(AbstractPersistentCollection.java:438) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
	at org.hibernate.collection.spi.PersistentBag.add(PersistentBag.java:385) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]

문제 해결

사실 해당 에러는 변경이 될때 @Transactional이 없어서 발생하는 로직인데 저 같은경우 생성 즉시 세팅이 되게 할려고 생성자에 해당 로직을 불러오게 만들고, service에서 생성하여 영속성 컨텍스트에 저장시켜 주었는데 아래와 같이 member를 직접적으로 넘게주면 에러가 발생하여 영속성 되어있는 Member를 불러오니 해결이 되었습니다.

예제 코드(문제가 있었던 코드)

ProblemCreateDTO.java

public record ProblemCreateDTO(String title, String subject, Member member) {
}

ProblemService.java

(...)

@Transactional
public Problem save(ProblemCreateDTO problemCreateDTO) {
    Problem problem = Problem.create(problemCreateDTO);
    problemRepository.save(problem);
	return problem;
}

(...)

Problem.java

(...)

private Problem(String title, String subject, Member member) {
    setMember(member);
    this.title = title;
    this.subject = subject;
	this.updateDate = LocalDateTime.now();
    this.createDate = LocalDateTime.now();
}

public static Problem create(ProblemCreateDTO dto) {
	return new Problem(dto.title(), dto.subject(), dto.member());
}

public void setMember(Member member) {
    this.member = member;
	member.getProblems().add(this);
}

(...)

해결된 코드

ProblemCreateDTO.java

public record ProblemCreateDTO(String title, String subject, Long memberId) {
}

ProblemService.java

(...)

@Transactional
public Problem save(ProblemCreateDTO problemCreateDTO) {
	Member member = memberRepository.findOne(problemCreateDTO.memberId());
	Problem problem = Problem.create(problemCreateDTO, member);
	problemRepository.save(problem);
	return problem;
}

(...)

Problem.java

(...)

public static Problem create(ProblemCreateDTO dto, Member member) {
	return new Problem(dto.title(), dto.subject(), member);
}

(...)

이제 정상적으로 생성되는 모습을 볼 수 있었습니다.