-->
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: Possible bug with composite id
PostPosted: Fri Apr 13, 2007 11:54 am 
Newbie

Joined: Fri Apr 13, 2007 10:58 am
Posts: 2
Hi, I'm using Hibernate v3.2.0 with Oracle 10 and having trouble with a composite id. I've simplified the code in order to make this readable.

I have a simple table with 3 fields, 2 of them compose the primary key.
Code:
table_test(key_1, key_2, val)

So I've created 2 classes, one for mapping the table and one for mapping the key.
Code:
class Test {
  String value;
  IdTest id;
}

class IdTest {
  String key1;
  String key2;
}

The mapping is like this :
Code:
<hibernate-mapping>
    <class
        name="Test"
        table="table_test"
        lazy="false"
    >
        <composite-id
            name="id"
            class="IdTest"
        >
                <key-property
                        name="key1"
                        type="string"
                        column="key_1"
                />
                <key-property
                        name="key2"
                        type="string"
                        column="key_2"
                />
        </composite-id>
        <property
            name="value"
            type="long"
            update="true"
            insert="true"
            column="val"
        />
    </class>
</hibernate-mapping>

Every single operation works fine (get, save, update...) but I have a trouble when I try to load a list of Test by the way of a list of IdTest.

I use this HQL query named "findTestsByIds" :
Code:
from Test where id in (:ids)

and call it that way :
Code:
public List getTests(List ids)
{
    final Session session = getCurrentSession();
    final Query query = session.getNamedQuery("findTestsByIds");
    query.setParameterList("ids", ids);
    return query.list();
}

If ids.size() is 1, everything works fine, I get a List of Test of size 1 with the Test corresponding to the given id.
But if ids.size() > 1, an SQLException is thrown by calling list(), due to an oracle 17041 error [Missing IN or OUT parameter at index: ...]

Full stacktrace :
Code:
org.hibernate.exception.GenericJDBCException: could not execute query
   at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.loader.Loader.doList(Loader.java:2147)
   at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2028)
   at org.hibernate.loader.Loader.list(Loader.java:2023)
   at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:393)
   at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
   at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
   at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
   at TestMain.main(TestMain.java:50)
Caused by: java.sql.SQLException: Missing IN or OUT parameter at index: 4
   at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
   at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
   at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:1681)
   at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3280)
   at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3329)
   at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:236)
   at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
   at org.hibernate.loader.Loader.getResultSet(Loader.java:1668)
   at org.hibernate.loader.Loader.doQuery(Loader.java:662)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
   at org.hibernate.loader.Loader.doList(Loader.java:2144)

If size is 2, for instance, the error message is "Missing IN or OUT parameter at index: 4".

The generated SQL request is :
Code:
SELECT tabletest0_.key_1 AS key1_37_, tabletest0_.key_2 AS key2_37_,
       tabletest0_.val AS val3_37_
  FROM table_test tabletest0_
WHERE (tabletest0_.key_1, tabletest0_.key_2) IN ((?, ?), (?, ?))


If I manually set the parameters, I get my 2 table_test records. And I'm sure that my list of ids is well filled. So I assume there must be a problem while setting the IN parameters.

My actual workaround is looping over the ids, loading the Test one by one and putting them into a list manually. But in term of performance, I don't think that it's the best way...

Thanks for your help !
Seb


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 15, 2007 8:06 pm 
Senior
Senior

Joined: Tue Mar 09, 2004 2:38 pm
Posts: 141
Location: Lowell, MA USA
As a general rule, your key class must implement equals() and hashCode(). It looks like your class does not.

Ryan-

_________________
Ryan J. McDonough
http://damnhandy.com

Please remember to rate!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 16, 2007 3:19 am 
Newbie

Joined: Thu Mar 29, 2007 7:03 am
Posts: 9
Location: Delhi
Hi

You can try by passing comma saperated string of values instead of list of values. Where each value should be in single quote.

For example if list has two values[a,b] then convert it in string as

'a,'b' and pass as argument to HQL.


Regards

_________________
Jini


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 16, 2007 4:22 am 
Newbie

Joined: Fri Apr 13, 2007 10:58 am
Posts: 2
@damnhandy
You're right, I have omitted these methods and also getters & setters from my comment to reduce its size.

In IdTest class, equals() is based on key1.equals(o.key1) && key2.equals(o.key2). In Test class, it's based on id.equals(o.id).

@ankit.zindal
I'm not sure to get your point. The list of ids is made of IdTest objects. So for each id in the list, I have a key1 and a key2 fields. Do you mean I should put all the key1 in one comma separated string and all the key2 in another one ?

Maybe it's more comprehensive with an example. Let's say I have 2 Test objects :

a = {id = {key1 = "a1", key2 = "a2"}, value = "a"}
b = {id = {key1 = "b1", key2 = "b2"}, value = "b"}

Should I create 2 lists keys1=[a1, b1] and keys2=[a2, b2] and then convert them into comma separated strings that I would pass as arguments to HQL ?

Thanks for your interest,
Regards.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 06, 2007 7:03 am 
Newbie

Joined: Wed Jun 06, 2007 6:17 am
Posts: 1
I am having exactly the same issue with Oracle 10 and composite ids.
It seems to be a bug, any news on this?

I change my code to use Query by Criteria instead and it seems to work.


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.