我剛開始瞭解FetchType Lazy和Eager。我瞭解其中的差異,但即使我設置爲Lazy,它仍以嘗試獲取相關數據。Spring Hibernate FetchType LazyInitializationException即使未調用關聯
關係:1人:許多手機
研究嘗試和教程瀏覽:
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/
我的理解,以獲得相關的數據我需要做它同時還在session()所以對於我的特定示例在我的Dao中,我需要類似這樣的東西
List<Person> persons = criteria.list();
for(Person person : persons){
Set sets = person.getPhones();
}
return persons;
到目前爲止是否正確?
但問題是我沒有調用person.getPhones()任何地方不在Dao,controller..etc但我得到LazyInitializationEception。對於我的生活似乎無法捕捉到什麼是錯的。
堆棧跟蹤
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);
}
}
控制器
// 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;
}
問題
只要我不叫會話應該會在person.getPhones()只返回人?如果是這樣,那麼我可能會遇到LazyInitializationException?
我還看到有人調用setFetchMode()FetchMode.JOIN在例如 Hibernate Criteria Join with 3 Tables 也許這可能是主觀的,但什麼DAO類將是一個更好的做法?任何性能問題?
任何想法,鏈接或文章大加讚賞...
UPDATE 由於Abassa從的toString Person.class中移除電話解決了這個問題。但我只是意識到,由於傑克遜,在序列化期間,它試圖獲取Phone ojbect ....是否有解決方法?
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
你是否在Person類的toString方法中打印手機屬性? –
當您需要指定如何獲取關係時,Fetchmode非常有用。 通過加入或選擇FecthMode。 請參閱文檔:https://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/FetchMode.html 根據您的數據庫模型,選擇其中一個可能會導致性能問題。 –
@AbassA是的,我必須親自試試 –