在Spring Boot中延迟加载

时间:2019-04-21 13:22:40

标签: java spring spring-boot

我有2个实体,我正在使用多对多关系加入他们。

public class MongoDb {

    private final MongoClient mongo;
    private final String databaseName;

    public MongoDb(URI url, String databaseName) {
        log.debug("Mongodb url:" + url);
        mongo = new MongoClient(url.getHost(), url.getPort());
        this.databaseName = databaseName;
    }

    @PreDestroy
    public void shutdown() {
        log.debug("Tearing down mongo.");
        final MongoDatabase db = mongo.getDatabase(databaseName);
        if (db != null) {
            db.drop();
        }
    }
}

package com.app.mms.entity;

import ...

@Entity
@Table(name = "insurance_company")
public class InsuranceCompany{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "name")
    private String name;

    @ManyToMany(fetch = FetchType.LAZY,
            cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinTable(name = "insurance_survey",
            joinColumns = { @JoinColumn(name = "id_insurance_company") },
            inverseJoinColumns = { @JoinColumn(name = "id_survey_company") })
    private List<SurveyCompany> surveyCompany;

   // Getters, setters and constructor
}

并具有2个Jpa存储库:

package com.app.mms.entity;

import ...

@Entity
@Table(name = "survey_company")
public class SurveyCompany{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "name")
    private String name;

    @ManyToMany(fetch = FetchType.LAZY,
        cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinTable(name = "insurance_survey",
            joinColumns = { @JoinColumn(name = "id_survey_company") },
            inverseJoinColumns = { @JoinColumn(name = "id_insurance_company") })
    private List<InsuranceCompany> insuranceCompany;

       // Getters, setters and constructor
    }

和我的 application.properties 包含:

package com.app.mms.dao;

import ...
@Repository
public interface InsuranceCompanyDao extends JpaRepository<InsuranceCompany, Long>{
}

package com.app.mms.dao;

import ...

@Repository
public interface SurveyCompanyDao extends JpaRepository<SurveyCompany, Long>{
}

我试图懒惰地检索实体,但出现异常:

spring.datasource.url=jdbc:h2:file:./Database/mmsdb;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=mms
spring.datasource.password=mms
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true

例外是:

System.out.println("All Survey companies:");
System.out.println(surveyCompanyDao.findAll());

System.out.println("All Insurance companies:");
System.out.println(insuranceCompanyDao.findAll());

// I imagine, after calling findAll() the session is already closed, 
//and then I try to retrieve the insurance company for that survey company because of lazy, and I get exception.
System.out.println(insuranceCompanyDao.findAll().get(0).getSurveyCompany());

如何在 Spring boot 中懒惰地检索数据?我找到了一些解决方案,他们在其中再次初始化了会话(默认情况下,Spring Boot在存储库中提供了该会话)。我不太确定这是否是正确的方法,因为我是Spring Boot的新手。如果有人可以解释在 spring boot 中懒惰地检索数据的正确方法,那就太好了。

修改

我的主班

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.app.mms.entity.InsuranceCompany.surveyCompany, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:602) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:217) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:581) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:148) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:537) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at java.lang.String.valueOf(String.java:2994) ~[na:1.8.0_112]
    at java.io.PrintStream.println(PrintStream.java:821) ~[na:1.8.0_112]
    at com.app.mms.MmsApplication.run(MmsApplication.java:63) [classes/:na]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:813) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    ... 10 common frames omitted

我的服务班级:

package com.app.mms;

import ...

@SpringBootApplication
public class MmsApplication implements CommandLineRunner{

    @Autowired
    InsuranceCompanyDao insuranceCompanyDao;

    @Autowired
    SurveyCompanyDao surveyCompanyDao;

   @Autowired
   InsuranceCompanyService service;


    public static void main(String[] args) {
        SpringApplication.run(MmsApplication.class, args);
    }

    @Override
    public void run(String... strings) throws Exception {
        System.out.println("In command line runner...");

        System.out.println("All Survey companies:");
        System.out.println(surveyCompanyDao.findAll());

        System.out.println("All Insurance companies:");
        System.out.println(insuranceCompanyDao.findAll());

     InsuranceCompany ic = insuranceCompanyDao.findAll().get(0);            
        System.out.println(service.getSurveyCompany(ic));

    }
}

0 个答案:

没有答案