-->
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.  [ 5 posts ] 
Author Message
 Post subject: positional parameter behaves different than named parameter
PostPosted: Mon Mar 14, 2011 11:14 am 
Newbie

Joined: Mon Mar 14, 2011 10:57 am
Posts: 3
Hello everybody!

I just found a difference between using a list type as named parameter and using it as positional parameter and wonder if this is the expected behaviour.
Here the example:
Code:
List<TreeNode> children = this.node.getAllChildren();

JPA.em().createQuery("DELETE FROM Folder WHERE node IN (:children)")
   .setParameter("children", children).executeUpdate();

In the example JPA.em() gives the current javax.persistence.EntityManager.
The code above works just as expected.

But when using the same parameter as positional parameter, i get an exception.
Code:
List<TreeNode> children = this.node.getAllChildren();

JPA.em().createQuery("DELETE FROM Folder WHERE node IN (?)")
   .setParameter(1, children).executeUpdate();

Quote:
Caused by: javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of models.TreeNode.id
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1214)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1147)
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1224)
at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:108)
at models.FileSystemObject.delete(FileSystemObject.java:106)
at controllers.api.FileSystem.deleteFolderById(FileSystem.java:116)
at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:515)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:476)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:453)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:448)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:155)
... 1 more
Caused by: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of models.TreeNode.id
at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:62)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:227)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3850)
at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3558)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:203)
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:242)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:456)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:130)
at org.hibernate.param.PositionalParameterSpecification.bind(PositionalParameterSpecification.java:68)
at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:93)
at org.hibernate.hql.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:421)
at org.hibernate.engine.query.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:283)
at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1288)
at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:117)
at org.hibernate.ejb.QueryImpl.internalExecuteUpdate(QueryImpl.java:188)
at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:99)
... 8 more
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Long field models.TreeNode.id to java.util.ArrayList
at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:59)
... 23 more

I only changed the parameter from a named parameter to a positional parameter.
Is this expected behaviour or a bug in Hibernate?

Thanks in advance!


Top
 Profile  
 
 Post subject: Re: positional parameter behaves different than named parameter
PostPosted: Wed Mar 16, 2011 4:24 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
positional parameters begin with index 0.

Try
Code:
JPA.em().createQuery("DELETE FROM Folder WHERE node IN (?)")
   .setParameter(0, children).executeUpdate();


Alternatively you also can assign the index explicitly

Code:
JPA.em().createQuery("DELETE FROM Folder WHERE node IN (?1)")
   .setParameter(1, children).executeUpdate();


Top
 Profile  
 
 Post subject: Re: positional parameter behaves different than named parameter
PostPosted: Wed Mar 16, 2011 8:39 am 
Newbie

Joined: Mon Mar 14, 2011 10:57 am
Posts: 3
Thanks for you're answer.

pb00067 wrote:
positional parameters begin with index 0.

No, they definitely don't.
Code:
JPA.em().createQuery("DELETE FROM Folder WHERE node IN (?)")
   .setParameter(0, children).executeUpdate();

Causes
Quote:
java.lang.IllegalArgumentException: org.hibernate.QueryParameterException: Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based! Position: 0
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:440)
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72)
at models.FileSystemObject.delete(FileSystemObject.java:105)
at controllers.api.FileSystem.deleteFolderById(FileSystem.java:116)
at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:515)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:476)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:453)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:448)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:155)
... 1 more

pb00067 wrote:
Alternatively you also can assign the index explicitly

When assigning an index explicitly it works like expected.

When using positional parameters without an explicit index for other parameter types like Long everything works.
Somehow it seems that there was broken more than this with list parameters in hibernate:

http://opensource.atlassian.com/project ... e/HHH-5126

I'm using 3.6.0 but will check the next days if that got fixed in 3.6.1 .


Top
 Profile  
 
 Post subject: Re: positional parameter behaves different than named parameter
PostPosted: Wed Mar 16, 2011 11:40 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Quote:
fgutmann wrote:
pb00067 wrote:
positional parameters begin with index 0.

No, they definitely don't.


Sorry, my message was not precise,. I hope following explanation is clearer:
-if you use Hibernate API directly then you must use '?' placeholders for positional parameter and the index starts with 0
-if you use Java Persistence API then you must use the '?index' placeholders where index begins with 1


Top
 Profile  
 
 Post subject: Re: positional parameter behaves different than named parameter
PostPosted: Wed Mar 16, 2011 12:10 pm 
Newbie

Joined: Mon Mar 14, 2011 10:57 am
Posts: 3
Thanks for the clarification - You are right.
Indeed it turns out that JPQL doesn't know positional parameters without an explicit index.

http://download.oracle.com/docs/cd/E110 ... pos_params

But still i think its strange behavior that hibernate excepts them when used with JPA in most cases but fails in certain ones.
It would be better if it always fails because its not standard or if it works with all types of parameters.
Personally i would prefer if it always fails, so it would enforce the standard.

Thanks again for you're help.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.