Question

I've a bit paradox question, but I'll try to explain it as meaningful as possible.

Background

I have a 3-tiered application setup involving Glassfish 3.1.2.2, JPA 2.0 (eclipse-link 2.3.3), MySQL database and a stand-alone Swing-Client. I access the EJB's with JNDI by remote interfaces. Moreover I use static weaving in order to benefit from lazy loading complex relations. On the stand-alone Swing client, I use load groups to selectively fetch only the relations I really need.

Goal

For the purpose of reducing network traffic, I plan to transform the queried @Entity annotated database objects to DTO's (Data Transfer Objects, POJO's) by using this model mapper.

The Big Issue

During the mapping of the @Entity-Objects to the corresponding DTO's, the accessors of each field on the @Entity is accessed which in turn does catch up all the non-fetched (lazy loaded indirect lists) fields from the database, resulting in big objects again.

My goal is to map the lazy-fetched @Entitiy annotated objects as they are, without fetching the intentionally non-fetched relations, in order to keep the objects as small as possible before they are being serialized and transfered to the remote client.

Any ideas ?

EDIT: I found this thread from someone using Dozer, I'm looking for something similar for ModelMapper.

What I tried so far (without success):

  • I detached the query result from the entity manager before mapping (still lazy fetching)
  • clearing and closing the entity manager after querying and before DTO-mapping (still lazy fetching)
  • declaring the queried List final (so that the lazy loading mechanism cannot

override attributes that are fetched afterwards, but it did)

Many thanks for your help in advance!

Was it helpful?

Solution

If your mapper cannot be configured to only map partial objects, then you can create a copy of the persistence object before passing it to the mapper.

Either use your own copy method that only copies the desired attributes, or you can use CopyGroups in EclipseLink,

http://wiki.eclipse.org/EclipseLink/Examples/JPA/AttributeGroup#Copy_Examples

OTHER TIPS

A JPA independent way would be to use the PersistenceProvider.isLoadedWithReference(entity, attribute) for each field, and just use null in the DTO if it wasn't loaded. This can be used to create the DTO directly, or in a CopyGroup as James suggested to make a scaled down entity instance of only fetched attributes.

You can use a global property condition to conditionally map properties that are not lazy. Here's an example using JPA2's PersistenceUnitUtil:

final PersistenceUnitUtil unitUtil = entityManagerFactory.getPersistenceUnitUtil();
modelMapper.getConfiguration().setPropertyCondition(new Condition<Object, Object>() {
  public boolean applies(MappingContext<Object, Object> context) {
    return unitUtil.isLoaded(context.getSource());
  }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top