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