-->
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: Problem using EntityMode.MAP, Criteria and ProjectionList
PostPosted: Mon Sep 29, 2008 4:41 pm 
Newbie

Joined: Wed Sep 10, 2008 2:47 pm
Posts: 8
Hibernate version: 3.2

Mapping documents:

<hibernate-mapping>
<class entity-name="USER" table="USER">
<id name="id" type="string" column="id">
<generator class="guid"/>
</id>
<property name="username" column="username" not-null="true" type="string" length="20"/>
<property name="fixedfield" column="fixedfield" not-null="true" type="string" length="20"/>
<property name="password" column="password" not-null="false" type="string" length="20"/>
<property name="givenname" column="givenname" not-null="true" type="string" length="20"/>
<property name="lastname" column="lastname" not-null="false" type="string" length="20"/>
<property name="email" column="email" not-null="false" type="string" length="20"/>
</class>

</hibernate-mapping>

Code between sessionFactory.openSession() and session.close():

I only want some fields (in the Set fieldNames) to be included in the query:

ProjectionList projectionList = Projections.projectionList();

for(String fieldName:fieldNames)
projectionList.add( Property.forName(fieldName));

Criteria criteria = session.createCriteria(ddoentity).addOrder(Order.asc("id"));

// criteria.setProjection(projectionList);

List<Map<String,Object>> list = (List<Map<String,Object>>) criteria.list();

-> for(Map<String,Object> object:list)
{
for(String attribute:object.keySet())
{
System.out.println("ATTRIB " + attribute);
System.out.println("VALUE " + object.get(attribute));
}
}



Full stack trace of any exception that occurs:

If I uncomment the commented line, I get the following error at the arrow line:

generated SQL:
Hibernate: select this_.id as y0_, this_.fixedfield as y1_, this_.username as y2_, this_.nickname as y3_, this_.givenname as y4_, this_.lastname as y5_ from USER this_ order by this_.id asc limit ?

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.Map

But everything goes right if I don't set the ProjectionList (if I leave it commented)

generated SQL:
Hibernate: select this_.id as id0_0_, this_.username as username0_0_, this_.fixedfield as fixedfield0_0_, this_.password as password0_0_, this_.givenname as givenname0_0_, this_.lastname as lastname0_0_, this_.nickname as nickname0_0_, this_.email as email0_0_, this_.textolibre as textolibre0_0_, this_.phone as phone0_0_, this_.other as other0_0_, this_.textolibre2 as textolibre12_0_0_, this_.other2 as other13_0_0_ from USER this_ order by this_.id asc limit ?

Name and version of the database you are using:

MySql 5


Please help me out with this, I think something is missing in my code


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 06, 2008 10:41 am 
Newbie

Joined: Tue Apr 01, 2008 3:34 pm
Posts: 10
Hi,

When you use a projection list you get back results as "tuples", not the object that was used as the basis of the criteria.

You probably just need to add a line like...

Code:
criteria.setResultTransformer( new AliasToBeanResultTransformer(DDOEntity.class) );


...when using the projection. On another note, this...

Code:
List<Map<String,Object>> list = (List<Map<String,Object>>) criteria.list();


...is a bit difficult to read and seems counter productive. Why not...

Code:
List <DDOEntity> list = criteria.list();


...? Your compiler will complain about the "unsafe" manner of this type conversion, but it will compile and run and you'll get a list of your DDOEntity objects. I'm actually kind of surprised that you can go from what should be a list of DDOEntity to a list of Map in the case where you're not using the projection. In fact, I would say that what you've posted would only work when using a projection and should not work with the projection commented out. I'm probably not reading your code quite right, or missing something here...

Anyway, hope that helps.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 06, 2008 3:45 pm 
Newbie

Joined: Wed Sep 10, 2008 2:47 pm
Posts: 8
Thank you very much for your reply midnightraver.

I'm not using classes (POJOs) to represent the entities of the system I am building. I'm using the MAP ENTITY MODE because my data model is essentially dynamic.

Let's suppose I define (at runtime, with help provided by the system) an entity named USER, with all of its attributes.

USER

-username
-givenname
-birthdate
-email
-active
-lastlogon
etc

Once the session factory is built, Hibernate generates and executes some DDL to create the corresponding tables in the DB.

To get a list of objects (maps) of the new entity, I follow these steps inside an hibernate session:

Criteria criteria = session.createCriteria("USER");
List<Map<String,Object>> list = (List<Map<String,Object>>)criteria.list();

That successfully returns a list of maps. Each MAP is a representation of a tuple of the entity:

[{ username: TEST,
givenname: TESTING,
...
lastlogon: 12/11/2008 11:25:16 },
{ username: ... },
{ username: ... }]

To do that, Hibernate executes a query like this against the DBMS:

Hibernate: select this_.id as id4_0_, this_.timestamp as timestamp4_0_, this_.username as username4_0_, this_.givenname as givenname4_0_, this_.birthdate as birthdate4_0_, this_.email as email4_0_, this_.active as active4_0_, this_.lastlogon as lastlogon4_0_ from USER this_ limit ?

Which is absolutely right.

The problem is that there will be entities with a big number of fields, and I don't need all of them to be fetched. I found a way to get hibernate to generate a smaller query, something like:

Hibernate: select this_.id as y0_, this_.username as y1_, this_.givenname as y2_ from USER this_ limit ?

I used a ProjectionList like this one for that:

ProjectionList projectionList = Projections.projectionList();
projectionList.add( Property.forName("username"));
projectionList.add( Property.forName("givenname"));
criteria.setProjection(projectionList);

The problem after that is that criteria.list() is no longer returning a list of maps, and it throws an exception:


java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.Map


I think my first post was not clear enough about my problem. Sorry about that.

Thanks again.
(I'm using hibernate 3.3.1)


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.