Cross fetch created on bi-directional One-to-many JPA / Hibernate query

拜拜、爱过 提交于 2019-12-13 03:58:17

问题


Here's the basic mapping:

Client {
    @OneToMany(mappedBy="client",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    private Set<Group> groups = new HashSet<Group>();
}

Group {
    @ManyToOne (cascade=CascadeType.ALL)
    private Client client = new Client();
}

The problem I'm having is that when I query against Client, I'm getting a full client for each associated group. My queries are pretty simple and I've tried both criteria and HQL. Here's a sample criteria query:

    Criteria crit = getSession().createCriteria(getPersistentClass());

    crit.add(Restrictions.like("name", name);
    crit.add(Restrictions.eq("state", state);

    return crit.list();

What the heck am I doing wrong?


回答1:


Modify your mapping of Client as below,

Client {
    @OneToMany(mappedBy="client",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private Set<Group> groups = new HashSet<Group>();
}

From the API docs,

You have the ability to either eagerly or lazily fetch associated entities. The fetch parameter can be set to FetchType.LAZY or FetchType.EAGER. EAGER will try to use an outer join select to retrieve the associated object, while LAZY will only trigger a select when the associated object is accessed for the first time. @OneToMany and @ManyToMany associations are defaulted to LAZY and @OneToOne and @ManyToOne are defaulted to EAGER.

Read the API docs here for more details.




回答2:


This is because of the fetch type eager. Hibernate is putting the groups in the same query, using joins. This multiplies the clients.

Join fetching of collections is usually not a good idea. It has several side effect. You just found one.

  • If you want to avoid lazy loading, just turn lazy off (I think it's the annotation @LazyCollection(FALSE))
  • If you don't care about the side effects: the multiplied clients you got from the query are still the same instances in memory. You could reduce them to a list of distinct instances.
  • HQL does actually not take this option into account. You need to join fetch them explicitly.


来源:https://stackoverflow.com/questions/9425765/cross-fetch-created-on-bi-directional-one-to-many-jpa-hibernate-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!