java - Hibernate- failed to lazily initialize a collection of role: beans.Language.patients, could not initialize proxy - no Session -
i use hibernate create rest api. create method items in table.
public list<language> getalllanguages(session session) { list<language> languages=(list<language>)session.createquery("from language").list(); return languages; }
this 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 patient.java
// generated sep 14, 2016 4:33:23 pm 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 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: beans , mappings reverse engineered mysql database, via netbeans. not need data related patient
when calling getalllangauges
. language
table has 2 columns, idlanguage
, language
. patient
table has foriegn key of language table
before using method in rest api , worked without exception. when used in rest api, created complexity in there.
i not using annotations in here. used hibernate reverse engineering wizard map above entities . rest api method.
@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 way how call 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>>() { }); (int = 0; < list.size(); i++) { system.out.println("id - " + list.get(i).getidlanguage() + " language - " + list.get(i).getlanguage()); }
when call method ,
failed lazily initialize collection of role: beans.language.patients, not initialize proxy - no session (through reference chain: java.util.arraylist[0]->beans.language["patients"])
is occurred.
interestingly, if did not close session, output below totally else, seems trying display foreign key tables , foreign key tables , 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 ideas problem ?
update
my configuration file
hibernate.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
<?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 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 patient mapping file,
patient.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 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 basic information of 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 serialize whole entity, contains list of patients speaking each language. understood, list of patient in json not expected. have 3 options (ordered in consider them) :
- remove mapping patients in language entity. need acces s patients language entity ? if not remove mapping.
- create language dto transfer data before exiting tx layer. way whoever calls service never lazyinitexception. no surprise : dto fields set eagerly.
- configure json converter not serialize patient fields. you've not said json lib you're using. of them give annotation ignore fields (
@jsonignore
jackson example), other requires java configuration.
to apply first solution, update files way :
language.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 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
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 no-arg constructor , setid
method protected
. can update them private
: hibernate should ever use them (and can use private fields / methods).
Comments
Post a Comment