无法使用SpringBoot延迟初始化角色集合

时间:2018-08-16 12:23:02

标签: hibernate spring-mvc spring-boot junit spring-data-jpa

我有一个基本的SpringBoot 2.0.3.RELEASE应用程序,它使用Spring Initializer,JPA,嵌入式Tomcat,Thymeleaf模板引擎和程序包作为可执行的JAR文件,在pom.xml中具有这些依赖性。

我有一个称为Company的域对象:

@Entity
@Table(name="t_company")
public class Company implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public Company() {
    }



    /**
     * @param companyName
     */ 
    public Company(String companyName) {
        super();
        this.name = companyName;
    }



    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @NotEmpty
    @Length(max = 100)
    private String name;


    @OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<User> users = new HashSet<>();

..
}

存储层:

public interface CompanyRepository extends CrudRepository<Company, Long> {

    @Query("select co from Company co join co.users us where co = ?1")
    Company companyUsers (Company company);

}

服务层:

@Service
@Transactional(readOnly = true)
public class CompanyService {

     @Autowired
     private CompanyRepository companyRepository;

     public Company companyUsers (Company company) {
        return companyRepository.companyUsers(company);
     }

}

Junit文件:

@Test
    public void testCompanyUsers() throws Exception {

        Iterable<Company> companies = companyService.findAll();
        Company company = companies.iterator().next();

        assertNotNull (company);

        company = companyService.companyUsers(company);
        assertTrue (((Collection<?>) company.getUsers()).size() > 0);           
    }

但是当我运行测试时,出现此错误:

  

无法延迟初始化角色集合:   com.cor.backend.persistence.domain.backend.Company.users,无法   初始化代理-没有会话

2 个答案:

答案 0 :(得分:2)

请仔细阅读以下文章:https://blog.arnoldgalovics.com/2017/02/27/lazyinitializationexception-demystified/

您的主要问题是,您正在尝试在事务之外访问实体引用。 您在这里有多种选择:

  • 在同一逻辑事务中获取必要的数据
  • 在JPQL查询中使用FETCH JOIN
  • 使用预测

有关预测的更多信息:https://blog.arnoldgalovics.com/2017/03/14/using-projections-in-your-data-access-layer/

还要考虑使用预测对性能的影响:https://blog.arnoldgalovics.com/2017/07/10/how-much-projections-can-help/

答案 1 :(得分:0)

对于springboot,我们需要添加@Transactional(org.springframework.transaction.annotation.Transactional) 到我们使用延迟加载属性的类: testCompanyUsers()

import org.springframework.transaction.annotation.Transactional;

...
@Transactional
public void testCompanyUsers() throws Exception {
...