2016-09-22 2 views
1

Я использую спящий режим для создания rest api. Я создаю метод для получения всех элементов в таблице.Hibernate - не удалось лениво инициализировать коллекцию роли: beans.Language.patients, не удалось инициализировать прокси - нет сеанса

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

Это мой 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; 
    } 

} 

И это мой 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; 
    } 
} 

Важно: Бобы и отображения обратной инженерии из базы данных MySQL, с помощью NetBeans , Мне не нужно получать какие-либо данные, связанные с patient при вызове getAllLangauges. Мой стол language имеет только 2 столбца, idlanguage и language. Patient таблица имеет знаковый ключ language table

Перед использованием этого метода в режиме отдыха api он отлично работал без каких-либо исключений. Но когда я использовал это в rest api, он создавал сложность там.

Здесь я не использую аннотации. Я использовал hibernate reverse engineering wizard для отображения над сущностями. Это мой метод 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; 
    } 
} 

Это способ, как я вызвать метод,

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()); 
} 

Когда я вызвать метод,

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"]) 

это произошло.

Интересно, что если я не закрыл сеанс, тогда я получаю вывод, как показано ниже, что является абсолютно чем-то другим, похоже, что он пытается отображать свои таблицы внешних ключей и их таблицы внешнего ключа и так далее ...

[{"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": 

Есть идеи по этой проблеме?

Update

мой конфигурационный файл

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

Это мой пациент отображения файла,

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 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> 
+1

@ MWiesner: Это не так. Ссылки, на которые вы ссылались, - это система, основанная на аннотациях, а OP - нет. Он создал свои бобы и картографию, используя обратную инженерию. Как мы все знаем, существуют некоторые различия между реализацией аннотации и не аннотацией, что также может привести к разным причинам для одной и той же проблемы. –

+0

Вы делаете что-то вроде language.getPatients(); – Gokul

+0

@Gokul: Нет. Я не – Barrier

ответ

1

Ваш конвертер JSON пытается сериализовать весь объект, который содержит список всех пациентов, говорящих каждый язык , Из того, что я понял, список пациентов в json не ожидается. Таким образом, у вас есть три варианта (упорядоченные, в которых я бы их рассмотрел):

  • Удалить картографирование пациентам в языковой среде. Вам нужно получить acces s пациентам из языкового образования? Если не удалить это сопоставление.
  • Создайте язык DTO, в котором вы передаете данные перед выходом из слоя tx. Таким образом, тот, кто называет службу, никогда не получит LazyInitException. Не удивительно: поля DTO всегда задаются с нетерпением.
  • Настройте ваш json-конвертер, чтобы не сериализовать поля пациента. Вы не сказали, какой json lib вы используете. Некоторые из них дают вам аннотацию, чтобы игнорировать некоторые поля (@JsonIgnore для Jackson, например), для других требуется конфигурация java.

Чтобы применить первое решение, обновление этих файлов таким образом:

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

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

Я обновил NO -arg конструктор и setId метод до protected. Вы можете даже обновить их до private: только hibernate должен когда-либо использовать их (и он может использовать частные поля/методы).

+0

Спасибо. Должен ли я сделать то же самое для других таблиц? – Barrier

+1

Это решение должно быть выполнено в каждом конкретном случае: я бы изменил двунаправленную связь на однонаправленную, если ваш код не использует одну из сторон (особенно если он удаляет '@ (One | Many) ToMany' боковая сторона). Для таблиц конфигурации (например, язык, страна, предпочтение и т. Д.), Зная, что все сущности, которые их используют, на самом деле не являются большим преимуществом. С другой стороны, '@ * ToMany' имеет много законных целей, поэтому не пытайтесь их удалить;) – Thierry

+0

Теперь у меня слишком много проблем с подключением. Посмотрите на это, http://stackoverflow.com/questions/39661594/hibernateexception-too-many-connections-using-c3p0 – Barrier

0

При попытке доступа ленивым поле вам нужно сделать это до начала сессии Hibernate закрыт.

Когда вы выходите из контекста сессии, невозможно, чтобы спящий режим мог получить доступ к базе данных, если это необходимо, поэтому вызывается LazyInitializationException.

От javadoc:

Указует доступ к несобранным данным вне контекста сеанса. Например, при доступе к неинициализированному прокси или коллекции после закрытия сеанса.

+0

Пожалуйста, проверьте обновленный вопрос. Кроме того, как реализовать, как вы упомянули? Вместо вызова save/get и т. Д. Мы должны взять 'Session' для обслуживания и выполнения работы? В любом случае сессия не закрывается перед получением результатов. – Barrier

+0

Привет? ............... – Barrier

0

Из настоящего объяснения я не могу видеть, что вы делаете так: language.getPatients();

Но если вы пишете запрос HQL для доступа ко всем пациентам из формы языка, я думаю, вам следует использовать join. Поскольку я могу видеть исключение, связанное с LazyInitializationException в beans.Language.patients.

так я предложу ниже код ... Проверьте это полезным для вас или нет ..

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

Вы используете hbm? – Gokul

+0

Я не использую язык для доступа к пациентам. – Barrier

+0

Можете ли вы поделиться своим файлом hbm ... Нет проблем с вашим pojo – Gokul

Смежные вопросы

 Смежные вопросы