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