Hibernate也会提取FetchType

Hibernate也会提取FetchType

本文介绍了即使未调用关联,Spring Hibernate也会提取FetchType LazyInitializationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始学习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);

返回数据;
}

问题


  1. 只要我不在会话中调用person.getPhones(),它应该只返回person?如果是这样,我可能会遇到LazyInitializationException的问题?

  2. 我还看到了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

  1. 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?

  2. 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 09:13