0

나는 Spring과 Hibernate와 lazy loading에 약간의 어려움이있다. 많은 질문과 답변이 있지만 실제로 내가 원하는 것은 아닙니다.Hibernate Spring JPA는 특정 게으른 관계만을로드한다.

따라서 Car 클래스가 있다고 가정 해 보겠습니다. id, namedoors, windowswheels과 일대 다 관계로. 그들이 oneToMany이기 때문에, 나는 선호하는 게으른 기본로드됩니다. 왜냐하면 내가 타이어와 물건을보고 싶지 않은 car의 이름을보고 싶기 때문입니다. 제 경우에는 제 저장소의 기본 findOne() 메소드를 사용합니다.

하지만 타이어 압력을보고 싶을 때 tires 관계를 초기화해야합니다. 나는 Hibernate.initialize(car.getTires())을 사용했다. 그러면 데이터베이스에 대해 다른 SELECT 쿼리가 생성됩니다. 이제 데이터베이스 쿼리를 개선하고 tires으로 car 만 선택하고 windowsdoors은 제외하십시오. (조인으로 MySQL에서 가능합니다). 내가 항상 내 물건에 대한 큰 관계가있는 tires 관계를로드하고 싶지 않기 때문에 열심히로드 할 수있는 옵션이 문제가되지 않습니다. 이것은 올바른 데이터를 제공합니까

@Query("SELECT c FROM Car c JOIN FETCH c.tires WHERE c.id = :id") 
Car findOneWithTiresLoaded(@Param("id") Long id); 

:

나는 다음과 같은 접근 방식을 시도했다. 그러나 저장소에서 반환 된 개체를 분석 한 후 모든 관계가로드 된 것으로 나타났습니다. 따라서 tires 관계가있는 car을 반환 할뿐만 아니라 doorswindows도 반환합니다. 다음은 나에게 (로드 moneToMany 관계와) 같은 출력 원하지 않는

@Query("SELECT c FROM Car c WHERE id = :id") 
Car findOneWithTiresLoaded(@Param("id") Long id); 

뭔가를 제공합니다. 이 모든 게으른 관계없이 Car 개체 만 출력 할 것으로 예상했습니다.

인터넷 사용자는 Car.getTires().size()으로 문의하십시오. 다른 SELECT 검색어도 생성됩니다.

Tires 관계 배송만으로 Car을 선택할 수있는 방법이 있습니까? fetch = FetchType.LAZY이 없으면 Hibernate.initialize() 또는 size() 방법을 사용 하시겠습니까? 하나의 테이블에 가입하는 것은 어떻게 불가능합니까? 또한, 나는 모든 구성에 XML을 사용하지 않습니다.

감사합니다!

답변

1

항상 엔티티 그래프를 사용하여 구현하는 것이 좋습니다. Spring Data를 사용하여 예제를 제공 할 것입니다. 또한 게으른 로딩은 무엇이든 관계없이 항상 사용되어야하며 다른 모든 관계는 특정 그래프를 사용하여 조인 될 수 있습니다.

이 방법을 사용하면 쿼리에 대해 매우 구체적 일 수 있으며 비즈니스 논리에 필요한 데이터 만 가져올 수 있습니다. 심지어 서브 그래프를 정의하여 tires 엔티티 중에서 선택할 항목을 표시 할 수도 있습니다. 즉, 모든 Tire 엔티티 관계에 대해 항상 게으른 페치를 수행해야합니다. 기본적으로 얻을 수있는 것은 tires (요청한대로)이며 다른 관계는 없습니다. tires에서 다른 것을 원한다면 나머지 그래프 정의를 정의하고 쿼리를 하위 그래프로 만드는 저장소에서 참조해야합니다.

@Entity 
@Table(name = "car") 
@NamedEntityGraph(name = Car.TIRES_GRAPH, attributeNodes = @NamedAttributeNode("tires")) 
public class Car { 

    public static final String TIRES_GRAPH = "Car.tires"; 

    @OneToMany(mappedBy = "car", fetch = FetchType.LAZY} 
    private Set<Tire> tires = new HashSet<>(); 

} 

그리고 당신의 저장소에 당신은 당신이 봄의 데이터를 사용하지 않는 경우에도 방법

@Query("SELECT c FROM Car c") 
@EntityGraph(Car.TIRES_GRAPH) 
Set<Car> findAllWithTires(); 

을 가질 수는 다음 방법은 동일하고 당신은 쉽게 그 좋은 예를 찾을 수 있습니다.

또 다른

편집 작업 예제를 테스트했다. 필드 이름이 스프링 데이터 용 도메인에서 일치하는지 확인하여 문제를 해결하십시오.

+0

내가'@ Table' 주석을 엔티티에 주석을해야합니까 문서에

public interface CarRepository extends JpaRepository<Car, Long> { @EntityGraph(attributePaths = { "tires" }) Set<Car> findAllWithTiresByCarId(Long id) } 

Link? 우리가 지금 당장 그렇게하지 않거나 필요하지 않다면 그것을 쓰지 않는 것이 더 낫습니다. 또는 Object 그래프와 함께 사용됩니까? 나는 이것을 지금 시도 할 것이다. 이것이 우리에게 효과가 있다면 당신의 답을 해결책으로 표시 할 것입니다. 답장을 보내 주셔서 감사합니다! – Clemenz

+0

'@ Table'을 생략 할 수는 없으며 단지 엔티티를 정의하는 데 사용됩니다. – Vaelyr

+0

방금 ​​"Car"클래스가 Vehicle 클래스를 확장한다는 것을 알았습니다. 그래서'@ Inheritance' 주석을 사용합니다. (또한 @DiscriminatorValue ('car') 주석). 'Car' 엔티티에서 명명 된 그래프를 사용하려고하면 부팅 할 때 오류가 발생합니다. '이 ManagedType [com.example.domain.Vehicle]'에 주어진 이름 [타이어]가있는 속성을 찾을 수 없습니다. 하지만'Car' 저장소의'Car' 테이블을 쿼리합니다. 무엇이 이것을 일으킬 수 있습니까? – Clemenz

관련 문제