Spring Boot 2.0.4.RELEASE默认获取

时间:2018-09-17 20:19:07

标签: java spring spring-boot jpa

我正在将Spring Boot与JPA(hibernate)结合使用,在我转向Spring Boot之前,我将Spring Data JPA与hibernate结合使用,默认设置是急于加载属性值并延迟加载集合。

在Spring Boot JPA中,默认情况下急切获取以下内容为什么?角色将在用户内部返回,但它们应该为空

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;

这就是我遵循的示例https://medium.com/@gustavo.ponce.ch/spring-boot-spring-mvc-spring-security-mysql-a5d8545d837d

我编辑的application.properties如下:

# ===============================
# = JPA / HIBERNATE
# ===============================
spring.jpa.show-sql = true
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

# ==============================================================
# = Spring Security / Queries for AuthenticationManagerBuilder
# ==============================================================
spring.queries.users-query=select email, password, active from user where email=?
spring.queries.roles-query=select u.email, r.role from user u inner join user_role ur on(u.id=ur.user_id) inner join role r on(ur.role_id=r.id) where u.email=?

================================================ =========================== 我试图在用户实体中添加此关系:

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

    @OneToMany(mappedBy = "user")
    private List<Test> tests;
}

测试将在此热切进行:

@Transactional
@Override
public List<User> getAllUsers() {
        List<User>users=userRepository.findAll();
    return users;
}

我找不到为什么这是默认设置而不是延迟加载。

3 个答案:

答案 0 :(得分:6)

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

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

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

    FetchType fetch() default LAZY;
}

答案 1 :(得分:2)

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

  1. 以前,由于配置错误,您的@Transactional无法正确应用
  2. 默认情况下,Spring Boot会为控制器启用OpenEntityManagerInViewInterceptor

Spring Boot为您管理事务,并且默认情况下将启用@Transactional的处理。因此,当使用调试器在@Transactional方法内检查结果时,由于正在进行的事务处理,仍然会检索到结果。

如果不是这种情况,您会看到OpenEntityManagerInViewInterceptor的效果。这导致在请求开始时打开EntityManager,并在视图渲染后将其关闭。

要禁用此行为(并假设您使用的是最新的Spring Boot版本),可以通过将spring.jpa.open-in-view属性设置为false来禁用它。

spring.jpa.open-in-view=false

答案 2 :(得分:0)

据我所知,根据this answer,请级联并获取其他问题。

默认情况下,@ManyToMany的访问方式如下:

@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;

    ....
}

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