-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Constructing Wrapper with Entity as Argument
PostPosted: Fri Mar 31, 2017 8:08 am 
Newbie

Joined: Fri Mar 31, 2017 5:57 am
Posts: 2
Hello,

I want to select an entity and pass it to a wrapper object. This works but leads to strange sql statements.
The following code shows the problem.

PersonEntity.java
Code:
package wrappertest;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class PersonEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    long id;

    private String name;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


PersonWrapper.java
Code:
package wrappertest;

public class PersonWrapper {

    private PersonEntity personEntity;

    public PersonWrapper(PersonEntity personEntity) {
        this.personEntity = personEntity;
    }
}



PersonWrapperTest.java
Code:
package wrappertest;

import com.movingimage24.vam.entity.AbstractDAOTest;
import org.junit.Test;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;

public class PersonWrapperTest extends AbstractDAOTest{

    @Test
    public void testWrapper() {
        PersonEntity personEntity = new PersonEntity();
        entityManager.persist(personEntity);
        transaction.commit();

        transaction.begin();
        entityManager.detach(personEntity);
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<PersonWrapper> criteriaQuery = criteriaBuilder.createQuery(PersonWrapper.class);

        Root<PersonEntity> root = criteriaQuery.from(PersonEntity.class);
        criteriaQuery = criteriaQuery.multiselect(root);
        List<PersonWrapper> resultList = entityManager.createQuery(criteriaQuery).getResultList();
    }
}


The sql statement shows that instead of selecting all columns and creating the entity out of it (like it will work when selecting the entity directly instead of the wrapper), hibernate selects the id column and makes single fetches
to create the entities. This has really a perfomance impact.

Code:
Hibernate: insert into PersonEntity (id, name) values (default, ?)
//I selected the root - why not selecting all columns?
Hibernate: select personenti0_.id as col_0_0_ from PersonEntity personenti0_
//single fetched to create the still entities
Hibernate: select personenti0_.id as id1_28_0_, personenti0_.name as name2_28_0_ from PersonEntity personenti0_ where personenti0_.id=?


So my question is - is it possible to pass an entity to a wrapper object without having single fetches?
Any help is highly appreciated.

You maybe argue that the example from above does not makes sense - in the case above you could just select the PersonEntity directly.
But there are uses cases where you may want to pass an entity togther with some other selected values from your query, this code is only for demonstrating the problem.

Greetings,
Holger


Top
 Profile  
 
 Post subject: Re: Constructing Wrapper with Entity as Argument
PostPosted: Mon Apr 03, 2017 6:30 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
This limitation might be optimized in Hibernate 6.0. However, meanwhile, you can use the following workaround:

Code:
List<PersonWrapper> personsWrappers = entityManager.createQuery(
   "select p " +
   "from Person p ")
.unwrap( Query.class )
.setResultTransformer( new ResultTransformer() {
   @Override
   public Object transformTuple(Object[] tuple, String[] aliases) {
      return new PersonWrapper(
         (Person) tuple[0]
      );
   }

   @Override
   public List transformList(List collection) {
      return collection;
   }
} )
.getResultList();


Check out this aticle for more details.


Top
 Profile  
 
 Post subject: Re: Constructing Wrapper with Entity as Argument
PostPosted: Mon Apr 03, 2017 8:08 am 
Newbie

Joined: Fri Mar 31, 2017 5:57 am
Posts: 2
Hello,

First of all - thank you for your time / response. I am using jpa 2.0. So it feels a bit "dirty" to have hibernate specific object in the unwrap method of the query.
Anyway - in the meantime get around my problem with using the tuple queries. Interesting enough your code somehow has also to do with tuple :-)
I am considering this post as done.

Good Day + Greetings,
Holger


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.