简体   繁体   English

Hibernate-无法延迟初始化角色集合:beans.Language.patients,无法初始化代理-没有会话

[英]Hibernate- failed to lazily initialize a collection of role: beans.Language.patients, could not initialize proxy - no Session

I use hibernate to create a rest api.我使用休眠来创建一个休息 api。 I create a method to get all items in a table.我创建了一个方法来获取表中的所有项目。

public List<Language> getAllLanguages(Session session) {
        List<Language> languages=(List<Language>)session.createQuery("from Language").list();
        return languages;
}

This is my Language.java这是我的 Language.java

public class Language  implements java.io.Serializable {


     private Integer idlanguage;
     private String language;
     private Set<Patient> patients = new HashSet<Patient>(0);

    public Language() {
    }


    public Language(String language) {
        this.language = language;
    }
    public Language(String language, Set<Patient> patients) {
       this.language = language;
       this.patients = patients;
    }

    public Integer getIdlanguage() {
        return this.idlanguage;
    }

    public void setIdlanguage(Integer idlanguage) {
        this.idlanguage = idlanguage;
    }
    public String getLanguage() {
        return this.language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }
    public Set<Patient> getPatients() {
        return this.patients;
    }

    public void setPatients(Set<Patient> patients) {
        this.patients = patients;
    }

}

And this is my Patient.java这是我的 Patient.java

// Generated Sep 14, 2016 4:33:23 PM by Hibernate Tools 4.3.1


import beans.DiabetesType;
import beans.Illness;
import beans.Language;
import beans.Reminder;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * Patient generated by hbm2java
 */
public class Patient  implements java.io.Serializable {

     private Integer idpatient;
     private DiabetesType diabetesType;
     private Language language;
     private String customId;
     private String diabetesOther;
     private String firstName;
     private String lastName;
     private String userName;
     private String password;
     private Date dateCreated;
     private Date lastUpdated;
     private Set<Illness> illnesses = new HashSet<Illness>(0);
     private Set<Reminder> reminders = new HashSet<Reminder>(0);


    public Patient() {
    }

    public Patient(Integer idpatient, String password) {
        this.idpatient = idpatient;
        this.password = password;
    }    

    public Patient(DiabetesType diabetesType, Language language, String customId, String firstName, String userName, String password, Date lastUpdated) {
        this.diabetesType = diabetesType;
        this.language = language;
        this.customId = customId;
        this.firstName = firstName;
        this.userName = userName;
        this.password = password;
        this.lastUpdated = lastUpdated;
    }
    public Patient(DiabetesType diabetesType, Language language, String customId, String diabetesOther, String firstName, String lastName,  String userName, String password, Date dateCreated, Date lastUpdated, Set<Illness> illnesses, Set<Reminder> reminders) {
       this.diabetesType = diabetesType;
       this.language = language;
       this.customId = customId;
       this.diabetesOther = diabetesOther;
       this.firstName = firstName;
       this.lastName = lastName;      
       this.userName = userName;
       this.password = password;
       this.dateCreated = dateCreated;
       this.lastUpdated = lastUpdated;
       this.illnesses = illnesses;
       this.reminders = reminders;
    }

    public Integer getIdpatient() {
        return this.idpatient;
    }

    public void setIdpatient(Integer idpatient) {
        this.idpatient = idpatient;
    }
    public DiabetesType getDiabetesType() {
        return this.diabetesType;
    }

    public void setDiabetesType(DiabetesType diabetesType) {
        this.diabetesType = diabetesType;
    }
    public Language getLanguage() {
        return this.language;
    }

    public void setLanguage(Language language) {
        this.language = language;
    }
    public String getCustomId() {
        return this.customId;
    }

    public void setCustomId(String customId) {
        this.customId = customId;
    }
    public String getDiabetesOther() {
        return this.diabetesOther;
    }

    public void setDiabetesOther(String diabetesOther) {
        this.diabetesOther = diabetesOther;
    }
    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getUserName() {
        return this.userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    public Date getDateCreated() {
        return this.dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }
    public Date getLastUpdated() {
        return this.lastUpdated;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }
    public Set<Illness> getIllnesses() {
        return this.illnesses;
    }

    public void setIllnesses(Set<Illness> illnesses) {
        this.illnesses = illnesses;
    }
    public Set<Reminder> getReminders() {
        return this.reminders;
    }

    public void setReminders(Set<Reminder> reminders) {
        this.reminders = reminders;
    }
}

Important: The beans and mappings are reverse engineered from MySQL database, via NetBeans.重要提示:bean 和映射是通过 NetBeans 从 MySQL 数据库逆向工程的。 I do not need to get any data related to patient when calling getAllLangauges .调用getAllLangauges时,我不需要获取任何与patient相关的数据。 My language table has only 2 columns, idlanguage and language .我的language表只有 2 列, idlanguagelanguage Patient table has a foriegn key of language table Patient表有language table

Before using this method in rest api , it worked perfectly without any exception.在 rest api 中使用此方法之前,它完美地工作,没有任何异常。 But when I used this in rest api, it created a complexity in there.但是当我在 rest api 中使用它时,它在那里创建了一个复杂性。

I am not using annotations in here.我没有在这里使用注释。 I used hibernate reverse engineering wizard to map above entities .我使用 hibernate 逆向工程向导来映射上面的实体。 This is my rest api method.这是我的休息 api 方法。

@Path("/language")
public class LanguageJSONService {

    @GET
    @Path("/getAllLanguages")
    @Produces(MediaType.APPLICATION_JSON)
    public List<Language> getAllLanguages(){
        LanguageService languageService=new LanguageService();
        List<Language> list = languageService.getAllLanguages();
        return list;
    }
}

This is the way how I call the method,这就是我调用方法的方式,

Client client = ClientBuilder.newClient();
List<Language> list = client.target("http://localhost:8080/simple_rest/rest")
                .path("/language/getAllLanguages")
                .request(MediaType.APPLICATION_JSON)
                .get(new GenericType<List<Language>>() {
                });

for (int i = 0; i < list.size(); i++) {
      System.out.println("Id - " + list.get(i).getIdlanguage() + " Language - " + list.get(i).getLanguage());
}

When I call the method ,当我调用方法时,

failed to lazily initialize a collection of role: beans.Language.patients, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->beans.Language["patients"])

is occurred.发生。

Interestingly, if I did not close the session, then I get an output like below which is totally something else, seems like it is trying to display its foreign key tables and their foreign key tables and so on...有趣的是,如果我没有关闭会话,那么我会得到如下输出,这完全是别的东西,似乎它正在尝试显示其外键表和它们的外键表等等......

    [{"idlanguage":1,"language":"English","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":{"iddiabetesType":1,"type":"Sever","patients":
[{"idpatient":1,"diabetesType":

Have any ideas about this problem ?对这个问题有什么想法吗?

Update更新

my configuration file我的配置文件

hibernate.cfg.xml休眠文件.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="show_sql">true</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/*****</property>
    <property name="hibernate.connection.username">*****</property>
    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">20</property>
    <property name="hibernate.c3p0.timeout">3000</property>
    <property name="hibernate.c3p0.max_statements">50</property>
    <property name="hibernate.c3p0.idle_test_period">300</property>
    <property name="hibernate.c3p0.testConnectionOnCheckout">true</property>
    <property name="hibernate.c3p0.preferredTestQuery">SELECT 1</property>
    <property name="hibernate.connection.password">************</property>
    <mapping resource="beans/Reminder.hbm.xml"/>
    <mapping resource="beans/Food.hbm.xml"/>
    <mapping resource="beans/Patient.hbm.xml"/>
    <mapping resource="beans/Illness.hbm.xml"/>
    <mapping resource="beans/Language.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

Language.hbm.xml语言.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 14, 2016 4:33:23 PM by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
    <class name="beans.Language" table="language" catalog="myglukose" optimistic-lock="version">
        <id name="idlanguage" type="java.lang.Integer">
            <column name="idlanguage" />
            <generator class="identity" />
        </id>
        <property name="language" type="string">
            <column name="language" length="45" not-null="true" />
        </property>
        <set name="patients" table="patient" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="language_idlanguage" not-null="true" />
            </key>
            <one-to-many class="beans.Patient" />
        </set>
    </class>
</hibernate-mapping>

This is my patient mapping file,这是我的患者映射文件,

Patient.hbm.xml病人.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 14, 2016 4:33:23 PM by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
    <class name="beans.Patient" table="patient" catalog="myglukose" optimistic-lock="version">
        <id name="idpatient" type="java.lang.Integer">
            <column name="idpatient" />
            <generator class="identity" />
        </id>
        <many-to-one name="diabetesType" class="beans.DiabetesType" fetch="select">
            <column name="diabetes_type_iddiabetes_type" not-null="true" />
        </many-to-one>
        <many-to-one name="language" class="beans.Language" fetch="select">
            <column name="language_idlanguage" not-null="true" />
        </many-to-one>
        <property name="customId" type="string">
            <column name="custom_id" length="45" not-null="true" />
        </property>
        <property name="diabetesOther" type="string">
            <column name="diabetes_other" length="45" />
        </property>
        <property name="firstName" type="string">
            <column name="first_name" length="100" not-null="true" />
        </property>
        <property name="lastName" type="string">
            <column name="last_name" length="100" />
        </property>        
        <property name="userName" type="string">
            <column name="user_name" length="45" not-null="true" />
        </property>
        <property name="password" type="string">
            <column name="password" length="45" not-null="true" />
        </property>
        <property name="dateCreated" type="timestamp">
            <column name="date_created" length="19" />
        </property>
        <property name="lastUpdated" type="timestamp">
            <column name="last_updated" length="19" not-null="true">
                <comment>Stores the basic information of the patient</comment>
            </column>
        </property>
        <set name="illnesses" table="illness" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="patient_idpatient" not-null="true" />
            </key>
            <one-to-many class="beans.Illness" />
        </set>
        <set name="reminders" table="reminder" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="patient_idpatient" not-null="true" />
            </key>
            <one-to-many class="beans.Reminder" />
        </set>
    </class>
</hibernate-mapping>

Your json converter tries to serialize the whole entity, which contains the list of all patients speaking each language.您的 json 转换器尝试序列化整个实体,其中包含使用每种语言的所有患者的列表。 From what i understood, the list of patient in the json is not expected.据我了解,json 中的患者列表不是预期的。 So you have three options (ordered in which i would consider them) :所以你有三个选项(我会考虑它们的顺序):

  • Remove the mapping to patients in Language entity.在语言实体中删除到患者的映射。 Do you need to get acces s to patients from the language entity ?您是否需要从语言实体访问患者? If not remove this mapping.如果没有删除此映射。
  • Create a Language DTO where you transfer your data before exiting the tx layer.创建一个语言 DTO,在退出 tx 层之前传输数据。 This way whoever calls the service will never get a LazyInitException.这样,调用服务的人永远不会得到 LazyInitException。 No surprise : DTO fields are always set eagerly.毫不奇怪:DTO 字段总是急切地设置。
  • Configure your json converter to not serialize the patient fields.将 json 转换器配置为不序列化患者字段。 You've not said which json lib you're using.您还没有说您使用的是哪个 json 库。 Some of them give you an annotation to ignore some fields ( @JsonIgnore for Jackson for example), other requires java configuration.其中一些为您提供了一个注释以忽略某些字段(例如@JsonIgnore用于 Jackson),其他需要 java 配置。

To apply the first solution, update those files this way :要应用第一个解决方案,请通过以下方式更新这些文件:

Language.hbm.xml语言.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 14, 2016 4:33:23 PM by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
    <class name="beans.Language" table="language" catalog="myglukose" optimistic-lock="version">
        <id name="idlanguage" type="java.lang.Integer">
            <column name="idlanguage" />
            <generator class="identity" />
        </id>
        <property name="language" type="string">
            <column name="language" length="45" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

Language.java语言.java

public class Language  implements java.io.Serializable {
    private Integer idlanguage;
    private String language;

    protected Language() {
    }


    public Language(String language) {
        this.language = language;
    }

    public Integer getIdlanguage() {
        return this.idlanguage;
    }

    protected void setIdlanguage(Integer idlanguage) {
        this.idlanguage = idlanguage;
    }
    public String getLanguage() {
        return this.language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }
}

I've updated the no-arg constructor and setId method to protected .我已将 no-arg 构造函数和setId方法更新为protected You can even update them to private : only hibernate should ever use them (and it can use private fields / methods).您甚至可以将它们更新为private :只有 hibernate 应该使用它们(并且它可以使用私有字段/方法)。

When you try to access a lazy field you need to do that before the session of hibernate is closed .当您尝试访问惰性字段时,您需要在关闭休眠会话之前执行此操作。

When you exit from the context of the session is not possible for hibernate to access the database if needed, so a LazyInitializationException is thrown.当您从会话的上下文中退出时,如果需要,休眠无法访问数据库,因此会抛出LazyInitializationException

From javadoc :javadoc

Indicates access to unfetched data outside of a session context .表示访问会话上下文之外未获取的数据 For example, when an uninitialized proxy or collection is accessed after the session was closed .例如,在会话关闭后访问未初始化的代理或集合时。

From current explanation I am not able to see you are doing like : language.getPatients();从目前的解释来看,我看不出你在做什么:language.getPatients();

But if you are writing HQL query to access all patients form Language Entity then I think you should use join .但是,如果您正在编写 HQL 查询以访问来自语言实体的所有患者,那么我认为您应该使用 join 。 As i can see the exception if related to LazyInitializationException in beans.Language.patients.因为我可以看到与 beans.Language.patients 中的 LazyInitializationException 相关的异常。

so i will suggest below code ...Check if it usefull to you or not..所以我会建议下面的代码......检查它是否对你有用..

public List<Language> getAllLanguages(Session session) {
        List<Language> languages=(List<Language>)session.createQuery("from Language as l JOIN l.patients").list();
        return languages;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 休眠-无法延迟初始化角色集合:无法初始化代理-没有会话 - Hibernate - failed to lazily initialize a collection of role: could not initialize proxy - no Session Hibernate 无法延迟初始化角色集合 无法初始化代理 - 没有 Session - Hibernate failed to lazily initialize a collection of role could not initialize proxy - no Session 无法延迟初始化角色集合无法初始化代理-无会话 - Failed to lazily initialize a collection of role could not initialize proxy - no Session 无法延迟初始化角色集合:无法初始化代理-无会话 - failed to lazily initialize a collection of role : could not initialize proxy - no Session DefaultExceptionListener:未能延迟初始化角色集合无法初始化代理 - 否 Session - DefaultExceptionListener : failed to lazily initialize a collection of role could not initialize proxy - no Session 无法延迟初始化角色[]的集合,无法初始化代理-没有会话 - failed to lazily initialize a collection of role [], could not initialize proxy - no Session Hibernate:LazyInitializationException:懒得初始化一个角色集合。 无法初始化代理 - 没有会话 - Hibernate: LazyInitializationException: failed to lazily initialize a collection of role. Could not initialize proxy - no Session org.hibernate.LazyInitializationException:无法延迟初始化role:ticketCircuitInfo的集合,无法初始化代理-没有会话 - org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:ticketCircuitInfo, could not initialize proxy - no Session Hibernate 延迟加载不适用于 Spring 启动 =&gt; 无法延迟初始化角色集合无法初始化代理 - 没有 Session - Hibernate Lazy loading not working with Spring Boot => failed to lazily initialize a collection of role could not initialize proxy - no Session 未能懒惰地初始化角色集合,..无法初始化代理 - 没有会话 - JPA + SPRING - failed to lazily initialize a collection of role,..could not initialize proxy - no Session - JPA + SPRING
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM