2017-10-16 1 views
1

그래서 나는 Comment 엔티티의 다음 매핑을 가지고 있습니다.식별자에만 액세스 할 때 지연 초기화를 방지하는 방법은 무엇입니까?

@Data 
@ToString(exclude = {"user", "place"}) 
@Entity 
public class Comment extends AbstractEntity { 

    @ManyToOne 
    private User user; 

    @ManyToOne 
    private Place place; 

    @Column(columnDefinition = "TEXT") 
    private String comment; 

    @Column 
    private Integer rating; 

    @Column 
    private Boolean approved; 
} 

나는이

Page<Comment> comments = commentRepository.findByApprovedIsFalseOrApprovedIsNull(pageable); 

같은 Comments를 가져 그리고 지금이

    <tr th:each="comment,i : ${comments}"> 
         <td><input name="places" th:value="${comment.id}" type="checkbox"></td> 
         <td th:text="${comments.number} * ${comments.size} + ${i.count}">LP1</td> 
         <td th:text="${comment.user.id}">1234</td> 
         <td th:text="${comment.place.id}">5432</td> 
         <td th:text="${comment.createdAt}">2014-04-10</td> 
         <td th:text="${comment.comment}">Lorem ipsum and more</td> 
         <td>Location</td> 
        </tr> 

같은 테이블로보기로 퍼팅 문제입니다 Comment 테이블에도 불구하고 (예,하지 엔티티) user_idplace_id 열이 포함되어있는 경우 추가 Place 및를 가져 오는 추가 선택이 수행됩니다.관계. 실제로 엔티티의 식별자에만 액세스하고 있기 때문에 실제로는 후드 아래에 Comment으로 숨겨져 있어야합니다. 왜 초기화가 수행 될까요? 추가 초기화 가져 오기를 생략 할 수 있습니까?

편집 :

나는 약간의 소스를 확인하신 후, 나는 BasicLazyInitializer는 단지 내가 필요 같은 식별자를 반환 할 수있는 능력을 가지고, 발견했다,하지만 난 잘 모릅니다, 조건은 위에서 레이어에 충족해야 할 일 이 지점을 appied해라. 여기를보십시오 : enter image description here

+0

가져 오기 및 선택 속성 '@ManyToOne (fetch = FetchType.LAZY, optional = false)'을 추가 했습니까? –

+0

@MadhusudanaReddySunnapu하지만 기본적으로 게으르며, 관계가 게으른 초기 초기화 된 문제는 내가 피하고 싶었던 것임을 나타냅니다. (이는 ID 가져 오기로 인해 잉여가되기 때문에) – Antoniossss

+0

아래에 제안 된대로 추가 필드를 매핑하거나 조인을 지정할 수 있습니다 1에서 모든 데이터를로드해야하는 쿼리에서 가져와 사용자 및 장소에 대한 추가 쿼리를 방지합니다. –

답변

2

확인을 한 번 봐, 그래서 내가 필요한 해결책을 가지고 있습니다. 여분의 JPQL이나 pirho과 같은 원시 쿼리는 필요하지 않으며 서비스와 같은 난독 화 해결 방법이 필요하지 않습니다.

우리가해야할 일은 을 private Long id; 필드에두고 나머지 속성에 대해 기본값을 @Access(AccessType.Field)으로 정의하면됩니다. @Access 주석으로 속성 액세스를 이미 사용하고 있거나 필드 대신 ORM 주석 가져 오기 도구를 사용하여 주석을 추가하는 경우에는 그 중 아무 것도 필요하지 않습니다.

@Data 
@MappedSuperclass 
@Access(AccessType.FIELD) 
public abstract class AbstractEntity { 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(updatable=false,nullable=false) 
    @Access(AccessType.PROPERTY) 
    private Long id; 

이것은 매력처럼 작동합니다. 관계의 ID 필드에 액세스하는 동안 N + 1 개의 쿼리가 없습니다.

0

외래 키를 읽기 전용 필드로 매핑 할 수 있습니다.

@Column(insertable=false, updatable=false) 
private Integer userId; 

@Column(insertable=false, updatable=false) 
private Integer placeId; 
1

당신은 뽀조

public class Response { 

    private Integer userId 

    private Integer placeId 

    private String comment; 

    public Response(Integer userId, Integer placeId, String comment){ 
    ..... 
    } 


} 


@Query("select new Response(c.user.id, c.place.id, c.comment) from Comment c where ....") 
private Resposne myCustomQuery(....) 

에 직접 매핑 할 수 있습니다 것은 https://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch11.html#ql-expressions 11.5

+0

- 원하는대로 작동하는 경우 - 올바른 방법, 모델과의 분리보기, IMHO – pirho

+0

- 이것은 내가 원했던 것과 비슷하지 않습니다. 뷰가 모델을 가져 와서 렌더링해야하는 것이 아니라면 다른 일시적 엔터티를 포함해야한다는 의미는 아닙니다.이 분리 점은 모델에 대한 지식이없는 뷰가 아니라 모델입니다. – Antoniossss

+0

"Kind a"i 명시된. 당신이 제공 한 위대한 및 귀하의 문제에 잘 적용됩니다.하지만 언제든지 ID를 – pirho