-->
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: select query works with java.util.Date but not java.sql.Date
PostPosted: Mon Sep 27, 2004 4:57 am 
Beginner
Beginner

Joined: Tue Jul 20, 2004 1:53 am
Posts: 43
Location: India
Hibernate version:Hibernate 2.16
Database: Oracle 9i

I have the following entity class :
Code:
package tavant.platform.persistence.hibernate.date;

import java.sql.Date;

public class Entity
{
    private Long id;
    private Date someDate;

    public Entity()
    {
    }

    public Entity(Long id, Date date)
    {
        this.id = id;
        this.someDate = date;
    }

    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public Date getSomeDate()
    {
        return someDate;
    }

    public void setSomeDate(Date someDate)
    {
        this.someDate = someDate;
    }
}


My mapping XML is as follows:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping package="tavant.platform.persistence.hibernate.date">
    <class name="Entity" table="MY_ENTITY">
        <id name="id" column="MY_ENTITY_ID" type="long">
            <generator class="sequence">
                <param name="sequence">MY_ENTITY_SEQ</param>
            </generator>
        </id>

        <property name="someDate" column="SOME_DATE" type="date"/>
    </class>
</hibernate-mapping>


With these I run the following test :
Code:
package tavant.platform.persistence.hibernate.date;

import net.sf.hibernate.Session;
import net.sf.hibernate.cfg.Configuration;

import java.util.List;

public class Test
{
    public static void main(String[] args) throws Exception
    {
        Session s = null;
        try
        {
            s = new Configuration()
                .setProperty("hibernate.connection.driver_class", "oracle.jdbc.driver.OracleDriver")
                .setProperty("hibernate.connection.url", "jdbc:oracle:oci8:@INFPRF01")
                .setProperty("hibernate.connection.username", "infra_persist")
                .setProperty("hibernate.connection.password", "persistence")
                .setProperty("hibernate.show_sql", "true")
                .setProperty("hibernate.dialect", "net.sf.hibernate.dialect.Oracle9Dialect")
                .addClass(Entity.class)
                .buildSessionFactory()
                .openSession();
            System.out.println("Opened Session");

            List list = s.createQuery("select new Entity(e.id, e.someDate) from Entity e")
                .list();
            System.out.println("Ran query");
        } finally
        {
            if (s != null)
            {
                s.close();
                System.out.println("Closed Session");
            }
        }
    }
}


This causes the following Exception :
Code:
net.sf.hibernate.PropertyNotFoundException: no appropriate constructor in class: tavant.platform.persistence.hibernate.date.Entity
   at net.sf.hibernate.util.ReflectHelper.getConstructor(ReflectHelper.java:214)
   at net.sf.hibernate.hql.QueryTranslator.renderSQL(QueryTranslator.java:560)
   at net.sf.hibernate.hql.QueryTranslator.compile(QueryTranslator.java:155)
   at net.sf.hibernate.hql.QueryTranslator.compile(QueryTranslator.java:138)
   at net.sf.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:294)
   at net.sf.hibernate.impl.SessionImpl.getQueries(SessionImpl.java:1562)
   at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1533)
   at net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:39)
   at tavant.platform.persistence.hibernate.date.Test.main(Test.java:46)


When I change my Entity class to use java.util.Date instead of java.sql.Date, the test works fine. The log is as follows :
Code:
2004-09-27 14:32:23,118,INFO,[main],[net.sf.hibernate.cfg.Environment],Hibernate 2.1.6
2004-09-27 14:32:23,133,INFO,[main],[net.sf.hibernate.cfg.Environment],hibernate.properties not found
2004-09-27 14:32:23,133,INFO,[main],[net.sf.hibernate.cfg.Environment],using CGLIB reflection optimizer
2004-09-27 14:32:23,149,INFO,[main],[net.sf.hibernate.cfg.Configuration],Mapping resource: tavant/platform/persistence/hibernate/date/Entity.hbm.xml
2004-09-27 14:32:23,352,INFO,[main],[net.sf.hibernate.cfg.Binder],Mapping class: tavant.platform.persistence.hibernate.date.Entity -> LOAN
2004-09-27 14:32:23,446,INFO,[main],[net.sf.hibernate.cfg.Configuration],processing one-to-many association mappings
2004-09-27 14:32:23,446,INFO,[main],[net.sf.hibernate.cfg.Configuration],processing one-to-one association property references
2004-09-27 14:32:23,446,INFO,[main],[net.sf.hibernate.cfg.Configuration],processing foreign key constraints
2004-09-27 14:32:23,477,INFO,[main],[net.sf.hibernate.dialect.Dialect],Using dialect: net.sf.hibernate.dialect.Oracle9Dialect
2004-09-27 14:32:23,477,INFO,[main],[net.sf.hibernate.cfg.SettingsFactory],Use outer join fetching: true
2004-09-27 14:32:23,493,INFO,[main],[net.sf.hibernate.connection.DriverManagerConnectionProvider],Using Hibernate built-in connection pool (not for production use!)
2004-09-27 14:32:23,493,INFO,[main],[net.sf.hibernate.connection.DriverManagerConnectionProvider],Hibernate connection pool size: 20
2004-09-27 14:32:23,493,INFO,[main],[net.sf.hibernate.connection.DriverManagerConnectionProvider],using driver: oracle.jdbc.driver.OracleDriver at URL: jdbc:oracle:oci8:@INFPRF01
2004-09-27 14:32:23,493,INFO,[main],[net.sf.hibernate.connection.DriverManagerConnectionProvider],connection properties: {user=infra_persist, password=persistence}
2004-09-27 14:32:23,508,INFO,[main],[net.sf.hibernate.transaction.TransactionManagerLookupFactory],No TransactionManagerLookup configured (in JTA environment, use of process level read-write cache is not recommended)
2004-09-27 14:32:25,821,INFO,[main],[net.sf.hibernate.cfg.SettingsFactory],Use scrollable result sets: true
2004-09-27 14:32:25,821,INFO,[main],[net.sf.hibernate.cfg.SettingsFactory],Use JDBC3 getGeneratedKeys(): false
2004-09-27 14:32:25,821,INFO,[main],[net.sf.hibernate.cfg.SettingsFactory],Optimize cache for minimal puts: false
2004-09-27 14:32:25,821,INFO,[main],[net.sf.hibernate.cfg.SettingsFactory],echoing all SQL to stdout
2004-09-27 14:32:25,821,INFO,[main],[net.sf.hibernate.cfg.SettingsFactory],Query language substitutions: {}
2004-09-27 14:32:25,821,INFO,[main],[net.sf.hibernate.cfg.SettingsFactory],cache provider: net.sf.hibernate.cache.EhCacheProvider
2004-09-27 14:32:25,821,INFO,[main],[net.sf.hibernate.cfg.Configuration],instantiating and configuring caches
2004-09-27 14:32:25,977,INFO,[main],[net.sf.hibernate.impl.SessionFactoryImpl],building session factory
2004-09-27 14:32:26,368,INFO,[main],[net.sf.hibernate.impl.SessionFactoryObjectFactory],Not binding factory to JNDI, no JNDI name configured
Opened Session
Closed Session
net.sf.hibernate.PropertyNotFoundException: no appropriate constructor in class: tavant.platform.persistence.hibernate.date.Entity
...


Does anyone here know what is going wrong?

_________________
Thanks,
Binil Thomas


Top
 Profile  
 
 Post subject: Re: select query works with java.util.Date but not java.sql.
PostPosted: Mon Sep 27, 2004 7:05 am 
Beginner
Beginner

Joined: Tue Jul 20, 2004 1:53 am
Posts: 43
Location: India
binil wrote:
Code:
2004-09-27 14:32:23,118,INFO,[main],[net.sf.hibernate.cfg.Environment],Hibernate 2.1.6
2004-09-27 14:32:23,133,INFO,[main],[net.sf.hibernate.cfg.Environment],hibernate.properties not found
2004-09-27 14:32:23,133,INFO,[main],[net.sf.hibernate.cfg.Environment],using CGLIB reflection optimizer
2004-09-27 14:32:23,149,INFO,[main],[net.sf.hibernate.cfg.Configuration],Mapping resource: tavant/platform/persistence/hibernate/date/Entity.hbm.xml
2004-09-27 14:32:23,352,INFO,[main],[net.sf.hibernate.cfg.Binder],Mapping class: tavant.platform.persistence.hibernate.date.Entity -> LOAN
...



Sorry, this log file is slightly wrong. The actual table I had used to perform my test was called LOAN, although I changed it in the mapping to say My_ENTITY.

Cheerio,
Binil

_________________
Thanks,
Binil Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 27, 2004 7:52 am 
Senior
Senior

Joined: Sun Jan 04, 2004 2:46 pm
Posts: 147
Because the return class of the hibernate date type is java.util.Date not java.sql.Date so it can't match the constructor.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 27, 2004 9:12 am 
Beginner
Beginner

Joined: Tue Jul 20, 2004 1:53 am
Posts: 43
Location: India
Myk wrote:
Because the return class of the hibernate date type is java.util.Date not java.sql.Date so it can't match the constructor.


Yeah, that seems to be the reason. The code where this happens is getConstructor method of net.sf.hibernate.util.ReflectHelper class (comment mine)
Code:
   public static Constructor getConstructor(Class clazz, Type[] types) throws PropertyNotFoundException {
      final Constructor[] candidates = clazz.getConstructors();
      for ( int i=0; i<candidates.length; i++ ) {
         final Constructor constructor = candidates[i];
         final Class[] params = constructor.getParameterTypes();
         if ( params.length==types.length ) {
            boolean found = true;
            for ( int j=0; j<params.length; j++ ) {
               //
               // java.sql.Date.class.isAssignableFrom(java.util.Date.class) returns false here !
               //
               final boolean ok = params[j].isAssignableFrom( types[j].getReturnedClass() ) || (
                  types[j] instanceof PrimitiveType &&
                  params[j] == ( (PrimitiveType) types[j] ).getPrimitiveClass()
               );
               if (!ok) {
                  found = false;
                  break;
               }
            }
            if (found) {
               if ( !isPublic(clazz, constructor) ) constructor.setAccessible(true);
               return constructor;
            }
         }
      }
      throw new PropertyNotFoundException( "no appropriate constructor in class: " + clazz.getName() );
   }


But if a property of type java.sql.Date is exposed as a setter and if I use a regular HQL, Hibernate seems to have no problem setting it - isnt this inconsistent behaviour? Someone knowledgeable kindly explain.

_________________
Thanks,
Binil Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 27, 2004 4:41 pm 
Senior
Senior

Joined: Sun Jan 04, 2004 2:46 pm
Posts: 147
It is correct that java.sql.Date is NOT assignable from java.util.Date. The reverse is. If hibernate was returning java.sql.Date and your program was java.util.Date ( or java.sql.Date ) it would find the constructor. I'm not sure why the DateType doesn't return java.sql.Date to be honest. Maybe one of the hibernate team could help there?


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:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.