Java Spring boot 2.0.4.0默认情况下发布

Java Spring boot 2.0.4.0默认情况下发布,java,spring,spring-boot,jpa,Java,Spring,Spring Boot,Jpa,我将SpringBoot与JPA(hibernate)结合使用,在我转到SpringBoot之前,我将SpringDataJPA与hibernate结合使用,默认情况下是急切地加载属性值,而惰性地加载集合 在SpringBootJPA中,默认情况下会急切地获取以下内容:为什么?角色将在用户内部返回,但应为null @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "user_role", joinColumns = @JoinCol

我将SpringBoot与JPA(hibernate)结合使用,在我转到SpringBoot之前,我将SpringDataJPA与hibernate结合使用,默认情况下是急切地加载属性值,而惰性地加载集合

在SpringBootJPA中,默认情况下会急切地获取以下内容:为什么?角色将在用户内部返回,但应为null

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
=========================================================================== 我已尝试在用户实体中添加此关系:

@Entity
@Table(name = "user")
@Getter
@Setter
public class User {

    @OneToMany(mappedBy = "user")
    private List<Test> tests;
}
@实体
@表(name=“user”)
@吸气剂
@塞特
公共类用户{
@OneToMany(mappedBy=“用户”)
私人列表测试;
}
测试将以以下方式进行:

@Transactional
@Override
public List<User> getAllUsers() {
        List<User>users=userRepository.findAll();
    return users;
}
@Transactional
@凌驾
公共列表getAllUsers(){
Listusers=userRepository.findAll();
返回用户;
}

我不明白为什么这是默认值而不是延迟加载。

你错了。默认情况下,以
toMany
结尾的每个映射都是延迟获取的
从Spring源文件复制:

@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface ManyToMany {

    // rest of the annotation properties are omitted for better readability

    FetchType fetch() default LAZY;
}

据我所知,级联并获取不同的关注点

默认情况下,
@manytomy
是如下所示的抓取延迟:


我只是想澄清一下,您是否在实体上使用lombok?

Spring Boot或Spring Data JPA会更改延迟解析集合的默认行为。使用Spring Boot时,您可能会遇到两种情况之一

  • 以前,由于配置错误,您的
    @Transactional
    未正确应用
  • Spring Boot默认为控制器启用OpenEntityManagerViewInterceptor
  • Spring Boot为您管理事务,并在默认情况下启用
    @Transactional
    的处理。因此,当使用调试器检查
    @Transactional
    方法内部的结果时,由于正在进行的事务,仍然会检索结果

    如果不是这样,您将看到OpenEntityManagerViewInterceptor的效果。这将导致在请求开始时打开
    EntityManager
    ,并在视图渲染后关闭它

    要禁用此行为(假设您使用的是最新的Spring引导版本),可以通过将
    Spring.jpa.openin view
    属性设置为
    false
    来禁用此行为

    spring.jpa.open-in-view=false
    

    这就是我所说的收藏。当你有很多的时候,你应该有一个收藏。但为什么在spring boot中我会有很多的加载呢?spring boot只是在spring的基础上构建,以简化应用程序的配置和运行。您的问题很可能与Spring Boot无关。是的,我使用lombok。请尝试删除lombok
    @Data
    注释并使用普通的旧getter setter?我使用的是@getter和@setter。我已经删除了它们和相同的问题您可以尝试在
    实体
    级别上添加
    @Access(AccessType.PROPERTY)
    。我们遇到了相同的问题,并用删除的lombok解决了它。很难说您共享的代码部分有什么问题。Spring Boot不会改变任何东西,Spring Data JPA也不会。集合不应为null,因为它是一个代理(将延迟检索集合)。但是,Spring Boot在默认情况下启用open entitymanager in view模式,该模式在http请求开始时打开
    entitymanager
    ,并在结束时关闭它。所以我猜你看到了这种行为。因此,不会将任何内容更改为“渴望”,它仍然是默认值。此外,如果您使用调试器检查
    getAllUsers
    中的列表,您仍然会看到它们,因为entitymanager已绑定到事务。@M.Deinum感谢您的回复。但在Spring数据JPA中,我可以在调试器中看到这些值为空。但我很困惑,如果这是一个代理,而不是急切地获取,我会得到与急切地获取相同的结果有什么区别?请参阅我的评论。。。打开的会话在视图中,可能是您现在有一个正确的事务,而您以前没有。@M.Deinum您能在下面发布答案吗?我会接受的it@M.Deinum请注意,我是在spring引导之前得到这个消息的:org.hibernate.LazyInitializationException未能延迟初始化集合,因此,如果您可以提及为什么我需要立即获取,如果延迟加载将根据需要获取它们,并且它将工作。什么情况下它不起作用?
    @Target({METHOD, FIELD})
    @Retention(RUNTIME)
    public @interface ManyToMany {
    
        ...
    
        /** (Optional) Whether the association should be lazily loaded or
         * must be eagerly fetched. The EAGER strategy is a requirement on
         * the persistence provider runtime that the associated entities
         * must be eagerly fetched.  The LAZY strategy is a hint to the
         * persistence provider runtime.
         */
        FetchType fetch() default LAZY;
    
        ....
    }
    
    spring.jpa.open-in-view=false