-->
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.  [ 12 posts ] 
Author Message
 Post subject: Request that a specific exception be added for this case
PostPosted: Fri Jul 23, 2004 3:14 pm 
Senior
Senior

Joined: Sun Oct 26, 2003 5:05 am
Posts: 139
I've noticed that if 'null' is passed into a query that is doing an equals test, this exception gets thrown by hibernate. While it didn't take me forever to find out what the heck happened, it wasn't very clear why it happened until I did some investigation for 4 or 5 minutes based on the exception trace.

The problem itself is rather obvious: the query should have been blah is null rather than blah = null, but in my case, I never wanted to compare null at all and I think a specific exception should be thrown to alert the programmer that this happened. In my very specific case, this exception was thrown because I didn't initialize my test case variable that contained the input for my query.

In any case, I think an exception should let the person know they tried to compare null with equals rather than 'is' to make it seem rather obvious.

Also, does this mean I have to add common code that traps these null cases and throws an application domain object not found exception? Should I do this for all queries?

Here is the exception for the query "From MyObject where number = ?" and 'null' was passed into the parameter. Thanks in advance for your response.

java.lang.NullPointerException
at net.sf.hibernate.proxy.HibernateProxyHelper.getClass(HibernateProxyHelper.java:34)
at net.sf.hibernate.impl.AbstractQueryImpl.guessType(AbstractQueryImpl.java:395)
at net.sf.hibernate.impl.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:385)
at org.springframework.orm.hibernate.HibernateTemplate$18.doInHibernate(HibernateTemplate.java:340)
at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:150)
at org.springframework.orm.hibernate.HibernateTemplate.executeFind(HibernateTemplate.java:170)
at org.springframework.orm.hibernate.HibernateTemplate.find(HibernateTemplate.java:337)
at com.upfactor.core.resource.hibernate.AbstractHibernateResource.findMany(AbstractHibernateResource.java:119)
at com.upfactor.core.resource.hibernate.AbstractHibernateResource.findOne(AbstractHibernateResource.java:107)
at com.upfactor.rns.resource.core.ReleaseOfficeResourceImpl.findByNumber(ReleaseOfficeResourceImpl.java:24)
at com.upfactor.rns.service.RnsTransactionServiceImpl.updateRnsTransaction(RnsTransactionServiceImpl.java:31)
at com.upfactor.rns.service.RnsTransactionServiceImpl.processRnsMessage(RnsTransactionServiceImpl.java:58)
at com.upfactor.rns.service.edi.RnsEdiMessageProcessor.processNode(RnsEdiMessageProcessor.java:12)
at com.upfactor.cig.Gateway.processEdiMessageNode(Gateway.java:49)
at com.upfactor.cig.message.contentstrategy.MultipartMixedContentStrategy.processEdiMessages(MultipartMixedContentStrategy.java:56)
at com.upfactor.cig.message.contentstrategy.MultipartMixedContentStrategy.processEdiObjects(MultipartMixedContentStrategy.java:44)
at com.upfactor.cig.message.contentstrategy.MultipartMixedContentStrategy.process(MultipartMixedContentStrategy.java:26)
at com.upfactor.cig.message.TransactionResponse.process(TransactionResponse.java:35)
at com.upfactor.cig.Gateway.sendDownloadRequest(Gateway.java:37)
at com.upfactor.cig.GatewayTest.testSendDownloadRequest(GatewayTest.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.intellij.rt.execution.junit2.JUnitStarter.main(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.intellij.rt.execution.application.AppMain.main(Unknown Source)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 3:16 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Welcome to ternary logic. You will have to use the "is null" operator in your query. There is nothing Hibernate can do here.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 4:12 pm 
Senior
Senior

Joined: Sun Oct 26, 2003 5:05 am
Posts: 139
christian wrote:
Welcome to ternary logic. You will have to use the "is null" operator in your query. There is nothing Hibernate can do here.


I know that. My point is that I never wanted to use ternary logic at all in this case. This was a bug with my junit test case - it really was supposed to do an equals on a valid string but it just happened that this string was null. I'm just saying that hibernate should throw an exeception based on this rather than "NullPointerException" to objects and methods I'm not supposed to know about. It would be nice if it let the callee know that the query could not compare null with the domain object property.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 4:14 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Hibernate "transports" ternary logic into Java, so its your decision. Setting null as a parameter is also a valid call, it shouldn't throw an exception.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 4:29 pm 
Senior
Senior

Joined: Sun Oct 26, 2003 5:05 am
Posts: 139
christian wrote:
Hibernate "transports" ternary logic into Java, so its your decision. Setting null as a parameter is also a valid call, it shouldn't throw an exception.


But it does...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 4:31 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Show the code you used, without any Spring noise.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 5:48 pm 
Senior
Senior

Joined: Sun Oct 26, 2003 5:05 am
Posts: 139
Code:
   public ReleaseOffice findByNumber( String number ) throws DomainObjectNotFoundException {
      if( number == null ) throw new DomainObjectNotFoundException();

      return (ReleaseOffice) findOne( "from ReleaseOffice where number = ?", number );
   }


findOne() does this:

Code:
   protected final Object findOne( String query, Object object ) throws DomainObjectNotFoundException {
      return getFirst( findMany( query, object ), query );
   }


findMany does this:

Code:
   protected final List findMany( String query, Object object ) {
      return getHibernateTemplate().find( query, object );
   }


That's the lowest my code does. The rest is spring.

getFirst() does this:

Code:

   private final Object getFirst( List list, String query ) throws DomainObjectNotFoundException {
      if( list.isEmpty() ) {
         throw new DomainObjectNotFoundException( "findOne() did not return a single object with the findMany '" + query + "'" );
      }

      return list.get( 0 );
   }



The mapping is

Code:
   <class name="com.upfactor.rns.domain.core.ReleaseOffice" table="release_office">
      <cache usage="read-write" />
      <id name="id" column="id" type="long" unsaved-value="0">
         <generator class="sequence">
            <param name="sequence">release_office_id_seq</param>
         </generator>
      </id>
      <property name="name" column="name" />
      <property name="number" column="number" />
   </class>



The query and mapping is so obvious that I am really am baffled. Thanks so much for the help.[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 5:50 pm 
Senior
Senior

Joined: Sun Oct 26, 2003 5:05 am
Posts: 139
Note that

Code:
if( number == null ) throw new DomainObjectNotFoundException();


is to prevent that NullPointerException from happening. I wish I wouldn't have to put it. I might just put it in findOne() so I don't have to think about it.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 6:12 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
The workaround is to specify the type of your bind parameter: s.find("from Foo f where f.bar = ?", null, Hibernate.STRING) would work. The Spring HibernateTemplate should provide this method. But you are right, Hibernate should throw an exception, as we can't guess the type of "null". I'll fix this.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 6:13 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Also note that the result of this query would still be semantically incorrect in almost all cases.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 6:33 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Fixed in CVS, the binding behavior for null parameters is now consistent for all find/query/setParameter methods. Thanks

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 23, 2004 11:59 pm 
Senior
Senior

Joined: Sun Oct 26, 2003 5:05 am
Posts: 139
christian wrote:
Fixed in CVS, the binding behavior for null parameters is now consistent for all find/query/setParameter methods. Thanks


Thanks so much. Glad I could help.


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