2017-06-19 2 views
0

Ich fange gerade an, über FetchType Lazy und Eager zu lernen. Ich verstehe den Unterschied aber selbst wenn ich auf Lazy setze ist es irgendwie immer noch versucht die zugehörigen Daten zu bekommen.Spring Hibernate FetchType LazyInitializationException auch wenn keine Verbindung aufgerufen wird

Beziehung: 1 Person: Viele Telefone

Forschungsversuche und Tutorials angesehen:

https://www.mkyong.com/hibernate/hibernate-one-to-many-relationship-example-annotation/ http://howtodoinjava.com/hibernate/lazy-loading-in-hibernate/ https://howtoprogramwithjava.com/hibernate-eager-vs-lazy-fetch-type/

Ich verstehe die zugehörigen Daten zu bekommen brauche ich werde es trotzdem noch tun in session() Also für mein spezielles Beispiel In meinem Dao brauche ich so etwas wie

List<Person> persons = criteria.list(); 

    for(Person person : persons){ 

     Set sets = person.getPhones(); 

    } 
    return persons; 

Soweit richtig?

Aber das Problem ist, ich rufe nicht person.getPhones() irgendwo nicht in Dao, Controller .. etc, aber ich bekomme LazyInitializationEception. Für das Leben von mir kann nicht scheinen, was falsch ist.

Stapelüberwachung

Jun 19, 2017 2:24:01 PM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [app-dispatcher] in context with path 
[/uni-starter-onetomany] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.app.person.Person.phones, could not initialize proxy - no Session] with root cause 
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.app.person.Person.phones, could not initialize proxy - no Session 

Person.class

@Entity 
@Table(name="person") 
@Component 
public class Person { 

@Id 
@GeneratedValue 
private int person_id; 

private String name; 

private String age; 

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "person") 
private Set<Phone> phones; 

// Getter and setters 

// ToString method by field name not by method 

Phone.class

@Entity 
@Table(name="phone") 
@Component 
public class Phone { 

@Id 
@GeneratedValue 
private int phone_id; 

private String type; 

private String phone; 

@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name="person_person_id") 
private Person person; 

// Getter and setters 

PersonDao

@Repository 
@Transactional 
@Component("personDao") 
public class PersonDao { 

@Autowired 
private SessionFactory sessionFactory; 

public Session session(){ 
    return sessionFactory.getCurrentSession(); 
} 

public List<Person> getPersonList(){ 
    Criteria criteria = session().createCriteria(Person.class); 

    List<Person> persons = criteria.list(); 

    // for(Person person : persons){ 
    // 
    // Set sets = person.getPhones(); 
    // 
    // } 

    return persons; 
} 


public void saveOrUpdate(Person person){ 
    session().saveOrUpdate(person); 
} 

}

-Controller

// Get list 
@RequestMapping(path="/list", method = RequestMethod.GET, produces="application/json") 
@ResponseBody 
public Map<String, Object> getListPerson(){ 

    Map<String, Object> data = new HashMap<String, Object>(); 

    List<Person> persons = personDao.getPersonList();  

    data.put("results", persons); 

    System.out.println(persons); 

    return data; 
} 

Frage

  1. Solange ich nicht nennen person.getPhones() in der Sitzung sollte es nur Rückkehrer? Wenn ja, was könnte das Problem hier sein, dass ich LazyInitializationException bekomme?

  2. ich gesehen, wie Menschen setFetchMode() FetchMode.JOIN in der Dao-Klasse zum Beispiel auch Hibernate Criteria Join with 3 Tables vielleicht dies subjektiv sein könnte, aber was wäre eine bessere Praxis sein? irgendwelche Leistungsprobleme?

Jede Idee, Links oder Artikel zu schätzen ...

UPDATE Dank Abassa Telefon Entfernung in von toString in Person.class behebt das Problem. Aber ich merke gerade, dass wegen Jackson während der Serialisierung versucht wird, Phone ojcect zu holen .... gibt es eine Arbeit herum?

Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: failed to lazily initialize a collection of role: com.app.person.Person.phones, could not initialize proxy - no Session 
+0

Drucken Sie Telefone Attribut in Ihrer toString-Methode in der Klasse Person? –

+0

Abrufmodus ist nützlich, wenn Sie angeben müssen, wie eine Beziehung abgerufen werden muss. Entweder durch Join oder Select FecthMode. Weitere Informationen finden Sie im Dokument: https://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/FetchMode.html Je nach Datenbankmodell kann die Auswahl einer dieser Optionen zu Leistungsproblemen führen. –

+0

@AbassA ja ich habe toString in Person –

Antwort

1

entfernen Feldtelefone von toString Methode in Klasse Person.

Wenn Sie anrufen:

System.out.println(persons); 

Sie versuchen, Felder Handys zugreifen, da println toString Methode für jede Person in der Liste nennt, so dass Sie die LazyInitializationException bekommen.

Verwandte Themen