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
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?
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
Drucken Sie Telefone Attribut in Ihrer toString-Methode in der Klasse Person? –
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. –
@AbassA ja ich habe toString in Person –