问题描述
我刚开始学习FetchType懒惰和渴望。我了解它们之间的差异,但即使我设置为Lazy,它仍然试图获取相关数据。
关系:1人:多个手机
研究尝试和教程观看:
我理解得到相关的数据,我仍然需要在session()因此,对于我的特定示例在我的Dao中,我需要类似这样的
列表< Person> persons = criteria.list();
(Person person:persons){
Set sets = person.getPhones();
}
退货人员;
到目前为止正确吗?
问题是我不调用person.getPhones()任何地方不在道,控制器..等但我得到LazyInitializationEception。对于我的生活似乎无法捕捉到什么是错误的。
堆栈跟踪
2017年6月19日下午2时24分1秒org.apache.catalina.core.StandardWrapperValve调用
SEVERE:servlet [app-dispatcher]中的Servlet.service()在路径
[/ uni-starter-onetomany]抛出异常[请求处理失败;嵌套的异常是org.hibernate.LazyInitializationException:未能懒惰地初始化一个角色集合:com.app.person.Person.phones,无法初始化代理 - 没有会话]的根本原因
org.hibernate.LazyInitializationException:失败懒惰地初始化一个角色集合:com.app.person.Person.phones,无法初始化代理 - 没有Session
Person.class
@Entity
@Table(name =人)
@Component
public class Person {
@Id
@GeneratedValue
private int person_id;
私人字符串名称;
私人字符串年龄;
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy =person)
private Set< Phone>手机;
// Getter和setters
//字段名的方法ToString而不是方法
Phone.class
@Entity
@Table(name =phone)
@Component
public class Phone {
@Id
@GeneratedValue
private int phone_id;
私有字符串类型;
私人字符串电话;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =person_person_id)
private Person person;
// Getter和setters
$ b 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);
列表< Person> persons = criteria.list();
//用于(Person person:persons){
//
// Set sets = person.getPhones();
//
//}
return persons;
}
public void saveOrUpdate(Person person){
session()。saveOrUpdate(person);
}
}
控制器
//获取列表
@RequestMapping(path =/ list,方法= RequestMethod.GET,产生=application / json)
@ResponseBody
public Map< String,Object> getListPerson(){
Map< String,Object> data = new HashMap< String,Object>();
列表< Person> persons = personDao.getPersonList();
data.put(results,persons);
System.out.println(persons);
返回数据;
}
问题
-
只要我不在会话中调用person.getPhones(),它应该只返回person?如果是这样,我可能会遇到LazyInitializationException的问题?
我还看到了Dao类中的setFetchMode()FetchMode.JOIN,例如
也许这可能是主观的,但是更好的做法是什么?任何性能问题?
任何想法,链接或文章都非常感谢...
更新
感谢Abassa在Person.class中删除来自toString的Phone in修复了这个问题。但我只是意识到,由于杰克逊,在序列化过程中,它试图获取Phone ojbect ....是否有解决方法?
无法编写HTTP消息:org.springframework.http.converter.HttpMessageNotWritableException:无法写入内容:无法延迟初始化角色集合:com.app.person.Person.phones,无法初始化代理 - 无Session
从 toString
$ b
System.out .println(人);
您尝试访问手机字段,因为println会为列表中的每个人调用toString方法,因此您可以LazyInitializationException。
I am just starting to learn about FetchType Lazy and Eager. I understand the difference but even if I set to Lazy its somehow still trying to get the associated data.
Relationship: 1 Person : Many Phones
Research attempts and tutorials viewed:
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/
I understand to get the associated data I will need to do it while still in session() So for my particular example In my Dao I will need something like this
List<Person> persons = criteria.list();
for(Person person : persons){
Set sets = person.getPhones();
}
return persons;
So far correct?
But the problem is I am not calling person.getPhones() anywhere not in Dao, controller..etc but I am getting LazyInitializationEception. For the life of me can't seem to catch what is wrong.
Stack trace
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;
}
Question
As long as I don't call person.getPhones() within the session it should only return person? if so what might be the problem here that I am getting LazyInitializationException?
I also seen people setFetchMode() FetchMode.JOIN in the Dao class for exampleHibernate Criteria Join with 3 Tablesperhaps this could be subjective but what would be a better practice? any performance issues?
Any idea, links or articles are much appreciated...
UPDATEThanks to Abassa removing Phone in from toString in Person.class fixes the problem. But I just realize that due to Jackson, during serialization it tries to fetch Phone ojbect.... is there a work around?
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
Remove phones field from toString method in Person class.
When you call:
System.out.println(persons);
you try to access phones fields because println calls toString method for every person in the list so you get the LazyInitializationException.
这篇关于即使未调用关联,Spring Hibernate也会提取FetchType LazyInitializationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!