JPA2/Hibernate - Stop lazy loading?

一个人想着一个人 提交于 2019-12-09 10:51:02

问题


I'm having a problem where JPA is trying to lazily load my data when I don't want it to. Essentially what is happening is I'm using a Service to retrieve some data, and when I go to parse that data into JSON, the JSON library is triggering hibernate to try and lazily load the data. Is there any way to stop this? I've given an example below.

// Web Controller method
public String getEmployeesByQuery(String query) {

    Gson gson = new Gson();
    List<Employee> employees = employeeService.findEmployeesByQuery(query);

    // Here is where the problem is occurring - the gson.toJSON() method is (I imagine)
    // using my getters to format the JSON output, which is triggering hibernate to
    // try and lazily load my data...
    return gson.toJSON(employees);
}

Is it possible to set JPA/hibernate to not try and lazily load the data?

UPDATE: I realize that you can use FetchType.EAGER - but what if I don't want to eager load that data? I just want to stop hibernate from trying to retrieve more data - I already have the data I want. Right now whenever I try and access a get() method hibernate will throw a "no session or session is closed" error, which makes sense because my transaction was already committed from my service.

Thanks!


回答1:


You really have two options:

  1. You can copy the data from employee to one that is not being proxied by hibernate.
  2. See if there is a way to not have the toJSON library reflect the entire object graph. I know some JSON libraries allow you to only serialize some properties of an object to JSON.

Personally I would think #1 would be easier if your library only uses reflection.




回答2:


There are several options:

  • If you always need to load your collection eagerly, you can specify fetch = FetchType.EAGER in your mapping, as suggested in other answers.

  • Otherwise you can enable eager fetching for particular query:

    • By using JOIN FETCH clause in HQL/JPQL query:

      SELECT e FROM Employee e JOIN FETCH e.children WHERE ...
      
    • By using fetch profiles (in JPA you can access Hibernate Session via em.unwrap(Session.class))



回答3:


As others have stated, this is not an issue with JPA/hibernate but rather with the json serialization library you are using. You should instruct gson to exclude the properties you don't want traversed.




回答4:


I suggest you to make a fetched copy of the entities you want to use outside of a transaction. That way, the lazy loading will occur from within a transaction and you can pass to Gson a plain, not enhanced, POJO.

You can use Doozer to do this. It is very flexible and through a little configuration (read you'll gonna loose your hair configuring it) you can even retrieve only partially the data you want to send to Gson.




回答5:


Yes:

@*ToMany(fetch=FetchType.EAGER)



回答6:


You could always change the fetch attribute to FetchType.EAGER, but it is also worth considering if you have your transactions have the right scope. Collections will be correctly loaded if they are accessed within a transaction.




回答7:


Your problem is that you are serializing the data. We ran into the same sort of problem with Flex and JPA/Hibernate. The trick is, depending on how much you want to mangle things, either

  1. Change your data model to not chase after the data you don't want.
  2. Copy the data you do want into some sort of DTO that has no relationships to worry about.
  3. Assuming you're using Hibernate, add the Session-in-view filter....its something like that, it will keep the session open while you serialize the entire database. ;)

Option one is what we did for the first big project we did, but it ruined the data access library we had for any sort of general purpose use. Since that time we've tended more toward option two.

YMMV




回答8:


The easy and straight forward thing to do is create new Data classes (something like DTO) use Hibernate.isInitialized() to check if the object is initialized by hibernate or not. I am checking gson if i can override anything. I will post it here if I find anything new.



来源:https://stackoverflow.com/questions/4805761/jpa2-hibernate-stop-lazy-loading

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