[SPRING] Spring Data JPA - @Transactional없이 가져온 Lazy Loaded 컬렉션
SPRINGSpring Data JPA - @Transactional없이 가져온 Lazy Loaded 컬렉션
내 예상은 게으른로드 된 컬렉션은 트랜잭션 범위 내에서 컬렉션에 액세스 할 때 가져와야한다는 것입니다. 예를 들어 컬렉션을 가져 오려면 foo.getBars.size ()를 호출 할 수 있습니다. 활성 트랜잭션이 없으면 다음과 같은 오류 메시지와 함께 예외가 발생합니다.
그러나 최근 응용 프로그램의 동작이 다른 것으로 나타났습니다. 나는 "data-jpa"시동기와 함께 Spring Boot 1.5.1을 사용하고있다. 과거에 Spring Boot를 사용했지만 data-jpa 스타터는 저에게 새로운 것입니다.
다음과 같은 경우를 고려하십시오. 나 게으른로드 ManyToMany 컬렉션이 있습니다.
@SuppressWarnings("serial")
@Entity
@Table(name = "foo")
public class Foo implements java.io.Serializable {
....
private Set<Bar> bars = new HashSet<Bar>(0);
....
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "foo_bar_map",
joinColumns = {@JoinColumn(name = "foo_id", nullable = false, updatable = false)},
inverseJoinColumns = {@JoinColumn(name = "bar_id", nullable = false, updatable = false)})
public Set<Bar> getBars() {
return this.bars;
}
public void setBar(Set<Bar> bars) {
this.bars = bars;
}
내 서비스 방법이 트랜잭션으로 표시되어 있지 않지만로드 된 컬렉션에 액세스하고 있습니다.
@Service
public class FooServiceImpl implements FooService {
@Autowired
private FooRepository fooRepo;
@Override
public FooDTO findById(int fooId) {
Foo foo = fooRepo.findOne(fooId);
// The FooDTO constructor will access foo.getBars()
return new FooDTO(foo);
}
그리고 FooDTO 생성자에 대한 컨텍스트
public FooDTO(Foo foo) {
...
for (Bar bar : foo.getBars()) {
this.bars.add(bar);
}
}
내 기대와 과거의 경험과는 달리이 코드는 성공적으로 실행되고 컬렉션을 가져옵니다. 또한 서비스 메소드에 중단 점을 던지면 코드를 한 단계 씩 실행하고 fooRepo를 호출 한 후 막대를 가져 오는 SQL 문을 로그에서 볼 수 있습니다. fooRepo에 전화를 건 후 거래가 종료 될 것으로 예상됩니다.
여기 무슨 일 이니?
해결법
-
==============================
1.스프링 부트는 기본적으로 OpenEntityManagerInView 인터셉터를 사용합니다. spring.jpa.open-in-view 속성을 false로 설정하여 해제 할 수 있습니다.
스프링 부트는 기본적으로 OpenEntityManagerInView 인터셉터를 사용합니다. spring.jpa.open-in-view 속성을 false로 설정하여 해제 할 수 있습니다.
이 (및 기타) JPA 등록 정보에 대한 참조 문서를 참조하십시오.
-
==============================
2.트랜잭션이 열려 있는지 확인하기 위해 로깅을 켤 수 있습니다.
트랜잭션이 열려 있는지 확인하기 위해 로깅을 켤 수 있습니다.
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction
또는
org.hibernate.engine.transaction.internal.jta.JtaTransaction
또한 중단 점을 설정하고이 정적 메소드를 사용하여 트랜잭션이 열려 있는지 확인할 수 있습니다.
org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive()
from https://stackoverflow.com/questions/42584454/spring-data-jpa-lazy-loaded-collection-fetched-without-transactional by cc-by-sa and MIT license