-->
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.  [ 7 posts ] 
Author Message
 Post subject: Using Multiple Projections and a ResultTransformer
PostPosted: Fri Dec 28, 2007 5:46 am 
Newbie

Joined: Fri Dec 28, 2007 5:05 am
Posts: 2
Hello all,

I want to retrieve a collection of entity class instances through creation of a Detached Criteria.

Let us suppose that I have an entity class called Person with the following properties:
- id
- name
- surname
- address

Now, I only want to retrieve a collection of Persons which contain the name and surname. For this I use multiple projections like so:

Code:
DetachedCriteria criteria = DetachedCriteria.forClass(Person.class);

//Define the projection list
ProjectionList projList = Projections.projectionList();
projList.add(Projections.property("name"));
projList.add(Projections.property("surname"));

//Set the projection list in our detached criteria
criteria.setProjection(projList);

//Retrieve the list of persons
List<Person> personList = getHibernateTemplate().findByCriteria(criteria)


But what I actually retrieve with this approach is a collection of Object collections which contain the values of the properties I set in my projection list.

Ok, fine. So I decide to set a result transformer in hopes of actually retrieving Person instances and not Object collection instances:

Code:
//Set the projection list in our detached criteria
criteria.setProjection(projList);

//Create and set result transformer
ResultTransformer resultTransformer = Transformers.aliasToBean(E2KAccounts.class);
criteria.setResultTransformer(resultTransformer);

//Retrieve the list of persons
List<Person> personList = getHibernateTemplate().findByCriteria(criteria)



With this, I do retrieve a collection of Person but all properties are null and while going through the debugger I get the following String when selecting elementData of the created Person list:

Quote:
Detail formatter error:
An exception occurred: java.lang.NullPointerException



And this String when selecting a Person object within the list:

Quote:
com.sun.jdi.InvocationException occurred invoking method.


So, my question is how do I properly retrieve the collection of Person I want instead of a collection of Object collections? I don't want to have to iterate through these objects and manually create a Person instance for each and proceed in mapping data from one object to another. I want to directly retrieve a list of Persons with projected property data properly set.

I have used result transformers before when using native SQL. In that case, I defined scalar maps for data mapping purposes. Should I be doing something similar here?

Thank you!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 04, 2008 3:07 pm 
Newbie

Joined: Wed Sep 27, 2006 3:34 am
Posts: 7
Hey i also need something similar to this.
Any solution?

_________________
koteshwar.venigalla@wipro.com


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 11, 2008 6:32 pm 
Newbie

Joined: Fri May 11, 2007 3:53 pm
Posts: 12
I have the same issue.

Any answer to this?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 13, 2008 3:14 pm 
Newbie

Joined: Fri May 11, 2007 3:53 pm
Posts: 12
From what I've read you can never retrieve an Entity from projections or transform the results into an Entity. It seems you can only do this with non-Entities.

I've noticed most of the examples I've seen use DTOs. So you if you had a Student Entity and only wanted a few properties (partially hydrated) that you end up creating a StudentDTO or some other object to hold those things. And they're filled in using the setters which match the property names and aliases.

I think the reason is b/c Hibernate's first level cache wouldn't be able to determine which object was what.

You could do a query and have a fully hydrated Student Entity with an id of 1. Then you could do a projection based query and if it was allowed to bring bck and entity and cache it that it would also have an id of 1 if it was the same student on partially hydrated. Then how would Hibernate be able to tell which object was which since it determines what is what by the id.

If any of my reasoning is wrong then I would DEFINITELY like to be told and if possible even pointed in the direction of where I can read or look at code to help explain this. I've looked through the manual and the projection section doesn't show you what to do with the *List* that is returned. I even read the tuple section where you end up with an iterator and an array of objects.

Is there some reason that there couldn't be a convenience method created to shove those results into an entity and not cache it? Or is the fear that someone would come along and try and save that partially hydrated object which would then corrupt the persisted values in the database?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 14, 2008 4:06 am 
Newbie

Joined: Fri Mar 14, 2008 3:44 am
Posts: 1
tri this

projList.add(Projections.property("name").as("name"));
projList.add(Projections.property("surname").as("surname"))

...........


ResultTransformer resultTransformer = Transformers.aliasToBean(Person.class);


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 14, 2008 2:31 pm 
Newbie

Joined: Fri May 11, 2007 3:53 pm
Posts: 12
Actually I figured out what the problem is. I didn't have any aliases on my projections. I guess I had assumed that if they Projections.projectionList().add(Projection.property("queueId")) would assume the alias name to be the same as the property name. After looking at the code this isn't the case.

And since it isn't you get your Entity object back with every field null. I wouldn't assume this is a desired result. But it could be as designed for a reason I'm unaware.

Could this be an enhancement to the AliasToBeanResultTransformer or maybe create a EntityResultTransformer ? Or is there a ResultTransformer that does this already? I looked through the API by searching for ResultTransformers and didn't find one that looked like it would do this for me.

Here is the code I used:

@SuppressWarnings("unchecked")
public void test() throws Exception {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
Criteria criteria = session.createCriteria(Queue.class);
ProjectionList projections = Projections.projectionList().add(Projections.property("queueId"), "queueId").add(
Projections.property("configurationXml"), "configurationXml");
criteria.setProjection(projections);

criteria.setResultTransformer(Transformers.aliasToBean(Queue.class));

List<Queue> list = criteria.list();

for (Queue queue : list) {
log.debug("whee:" + queue.getQueueId() + " " + queue.getConfigurationXml());
}

transaction.commit();
session.close();
}

And if it was just Projections.property("queueId).add(Projections.property("configurationXml") then the Queue object comes back with all fields null.

However since you did look at this issue and post the same conclusion I came to I will definitely rate your post. I appreciate you taking the time to look into this.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 14, 2008 2:36 pm 
Newbie

Joined: Fri May 11, 2007 3:53 pm
Posts: 12
Aww boo I can't rate since I'm not the original poster :(


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.