Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 仅访问标识符时如何防止延迟初始化?_Spring_Jpa_Spring Data - Fatal编程技术网

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

Spring 仅访问标识符时如何防止延迟初始化?,spring,jpa,spring-data,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

因此,我有以下
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);
                    <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>
Page comments=commentRepository.findbyapprovedisfalse或pprovedisnull(可分页);
把它放在像这样的桌子上

 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>

LP1
1234
5432
2014-04-10
Lorem ipsum及更多
位置
现在的问题是,尽管
Comment
表(是,不是实体)包含列
user\u id
place\u id
,但执行额外的选择以获取不同的
place
user
关系。由于我只访问那些实体的标识符,它们实际上应该已经隐藏在带有
注释的引擎盖下,为什么会发生初始化?是否可以对这些额外的初始化回迁进行ommit

编辑:

我检查了一些源代码,发现
BasicLazyInitializer
只能够按照我的要求返回标识符,但我不知道在顶层必须满足哪些条件才能应用此分支。请看这里:

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

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

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

您可以直接映射到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(....)
看看
11.5

好的,我有一个我需要的解决方案。它不需要额外的JPQL,也不需要像pirho提到的本地查询,也不需要像建议的72个服务那样的模糊处理

我们所要做的就是把
@Access(AccessType.PROPERTY)
放在
私有长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查询。

您是否尝试添加fetch和可选属性,即“@MANYTONE(fetch=FetchType.LAZY,optional=false)”?@MADHUSUDANAREDYSUNNAPU,但默认情况下它们是惰性的,而且整个问题都是关系被惰性初始化,这是我想要避免的(因为它仅因ids fetch而剩余)您可以按照下面的建议映射其他字段,或者在查询中指定一个连接获取,该连接获取应在1go中加载所有数据,并防止对User和Place进行额外查询。@Antoniossss Per JPA,“*ToOne”关系默认情况下是急切的,“*ToMany”默认情况下是惰性的,除非我们重写它们。好的,因此我声明了惰性获取,并且效果仍然相同。调用getId()时,代理将初始化:(如果按照需要工作,这将是正确的方法,将视图与模型分离,IMHOThis-甚至与我想要的不太接近。视图-模型分离并不意味着你必须包含另一个瞬态实体,除非它是投影。视图应该取一个模型并渲染它。这就是这种分离的意义,而不是视图不了解模型。“种类a”我说。您提供的解决方案很棒,可以很好地应用于您的问题。但是,如果您随时需要任何任意属性,而不仅仅是id?@pirho,那么它是一个
@列
,获取id是获取“隐藏”的一个特殊用例property.Rest将映射为字段。@Antoniossss我不同意您的看法。视图必须与模型不同,您不能将模型(实体)公开给View/Rest api。您可能会遇到LazyInitializationException等严重问题。例如,当您呈现给视图时:“${comment.user.id}”当您获得任何关联(在渲染阶段)时,您正在从视图中创建一个新查询。因为只有在调用getxxx方法时才会加载该关联。