如何在仅访问标识符时防止延迟初始化?

时间:2017-10-16 10:01:51

标签: spring jpa spring-data

所以我有以下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;
}

我像这样提取Comments

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

并按照这样的表格将其放入视图中

                    <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列,但还会执行其他选择以获取不同的PlaceUser关系。由于我只访问那些实体的标识符,实际上应该已经隐藏在Comment的引擎盖下,为什么会进行初始化?是否可以省略那些额外的初始化提取?

编辑:

我检查了一些来源,我发现BasicLazyInitializer只能按照我的要求返回标识符,但我不知道,顶层需要满足哪些条件才能获得此分支appied。看看这里: enter image description here

3 个答案:

答案 0 :(得分:2)

好的,所以我有一个我需要的解决方案。它不需要额外的JPQL,也不需要像 pirho 这样的本机查询,也不需要像 72 Services 那样混淆解决方法。

我们所要做的就是将@Access(AccessType.PROPERTY)放在private Long id;字段上,并为其余属性定义默认@Access(AccessType.Field)。如果您已经通过@Access注释使用属性访问,或者使用ORM注释getter而不是字段进行注释,则无需执行任何操作。

@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个查询。

答案 1 :(得分:1)

您可以直接映射到Pojo

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

答案 2 :(得分:0)

您可以将外键映射为单独的字段为只读。

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

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