Dozer Mapping Ignore Hibernate Lazy Loading - Spring - java

I am using Apache CXF with Spring and Dozer Mapper to convert DTOs (Database Objects) in to models. For Hibernate side I have enabled lazy="extra" and lazy="true" for mapping and which works fine hibernate loads child whenever respective getter methods are called. But when I convert DTO using dozer mapper it calls getter methods of all the child object in some case it was not necessary but in some it is not necessary. Is there any way by using which I can reduce overheads.

If you convert entities to DTOs, you have two options:
do not use lazy collections
ignore the collections when serializing, if you don't want them in the output

Fetch(load) child's always in every call results to heavy process and
unnecessary data to persist. So instead of doing this always fetch
data as lazy and initialize child's model whenever there is
need. This is the best way to fetch data.

Related

JPA+Hibernate force JPA not to use Proxies on Lazy loading

We are using JPA + Hibernate.
I have some Many-to-one mappings which are lazy loaded.
In Service, I Initiallize the Many-to-one objects by calling their getter method. but proxy gets assigned to parent VO and not actual VO Object.
My Question is, Is there any way in JPA to force to use no proxy Strategy.
My limitation here is i cant use Hibernate Objects or annotaions like #LazytoOne etc.
thanks in advance.
You cannot prevent Hibernate from using proxy objects there due to the fact that somehow it has to guarantee it's a lazy relation.
You have multiple choices:
Trigger the initialization Hibernate.initialize(parent.getChild()). Note that this is not the best way to do it and this also requires an active transaction.
Fetch the relation when fetching the entity itself. This can be done with the Fetch Joins. JPQL/HQL/Criteria API are capable of doing this.
Use read-only projections which contains only the data you need. For this particular case you can use Spring Data JPA as it comes with such a feature.
I suggest you to go with either option 2 or 3 as they are the most effective ways to do this.
Furher reading about lazy-loading here.

Fetch an object without its relationships/children using Hibernate/JPA

I using Hibernate/JPA and I need to fetch an object without its relationship/children How can I do that? The questions is not about to use Lazy or Eager strategy because in both case the children are attached to the object, initializate or not.
Ex: I have a obj A with a onetomany relationship to B. I want to fetch a list of A without the B attached to it.
Thanks
You can use DTO pattern which is desirable in RESTfull services.
Be sure to have only fields that you need and you can use spring ModelMapper to convert entity to dto.
http://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application
..or implement builder (lombok) or populator/converter pattern
Lazy loading will not fetch the child records until otherwise you call for the child record's getter method. So you can use this in your case.
Note: In lazy loading child record will not be attached unless otherwise it's getter is invoked.

Hibernate: Empty collection instead of Lazy-load error

I have an ORM entity loaded by Hibernate, with certain associations LAZY loaded when I need them. This entity is transported thru MQ to client application (and the client is .NET, so I'm using MessagePack to serialize/deserialize) and when the entity is serialized by MsgPack, it tries to access the lazy loaded association and it fails, as the session is already closed. And even if it did not failed, I do not want it to load the association in some cases.
Is there a way to tell hibernate to fill the lazy associations with empty values instead of proxies for some query results or do I have to iterate the returned list and perform these changes by myself?
Thanks for your answers!
You have no other way, but to use DTO objects, to tranfer it through MQ,
Load entity from DB using hibernate
convert it to DTO object which implents Serializable.
Transfer it to consumer using MQ
Convert it to any other entity on other side.
I think that #Transient only applies to ORM. If you do not want your field to be serialized, you should use key word "transient".
private transient List<Object> myTransientList;

Is there a way to expose Hibernate Entities as RESTful resources without DTOs?

I am developing a simple webapp which exposes the domain model as RESTful resources.
I am planning to use JPA2(Hibernate) with SpringMVC REST support.
While marshalling Hibernate entities into XML/JSON, if the entity is detached it will throw LazyLoadingException for lazy child associations. If the entity is still attached to Hibernate Session it will almost load whole database.
I have tried using Dozer CustomFieldMapper to determine if the property is lazy Hibernate Collection which is not loaded then return NULL.
But if we have bi-directional associations Hibernate eagerly load Many-to-One side and Dozer will try to copy properties which will end up in infinite loop resulting StackOverflow error.
The only work around that I know to resolve this is using DTOs and copying the required properties only into clean POJOs(DTOs) and marshalling then into XML/JSON. But it is terribly painful for complex domain model to copy properties manually.
Is there any other clean/simpler way to (un)marshall Hibernate entities?
I might sound too conservative but I consider using DTOs still a good idea.
The complexity of your mappings is proportional to the granularity of your resources' API, in other words the coarser the more complex.
I have had an analogous problem with passing Hibernate'd VO's back and forth in GWT applications, and in some projects used Dozer to good effect, and in other projects used the approach described in this article, which basically null's the hibernate proxies before marshalling.
Hope that helps you,
Take a loot at this class: https://github.com/viniciuspires/reqlist/blob/master/src/main/java/org/reqlist/arch/HibernateAwareObjectMapper.java
I'm using Jackson as a JSON serializer/deserializer, and I had to make this class and add the Hibernate4Module for it to verify if Hibernate.isInitialized and don't accidentaly initialize the property.
After that you just have to configure it as your ObjectMapper, and pass it to the MessageConverters array, as I did in this line:
https://github.com/viniciuspires/reqlist/blob/master/src/main/resources/META-INF/org.reqlist.context.xml#L21
That worked like a charm for me.

JPA2/Hibernate - Stop lazy loading?

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!
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))
You really have two options:
You can copy the data from employee to one that is not being proxied by hibernate.
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.
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.
Yes:
#*ToMany(fetch=FetchType.EAGER)
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.
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.
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
Change your data model to not chase after the data you don't want.
Copy the data you do want into some sort of DTO that has no relationships to worry about.
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
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.

Categories