-->
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.  [ 7 posts ] 
Author Message
 Post subject: PSQLException from polymorphic query on "any"
PostPosted: Tue Jun 06, 2006 10:42 am 
Newbie

Joined: Fri Nov 11, 2005 1:34 pm
Posts: 5
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

When I try to query on an "any" association (i.e. find all objects with a certain object in one of its fields, and that field is a java interface), I get an error from inside postgres complaining that too many columns are being bound. It is very easy to reproduce with just a little code, all of which is included below. Can anyone help me get past this? I have to use an any here; I have many classes that implement many different interfaces and this is the only way to map the associations.

Hibernate version: 3.2

Mapping documents:

Code:

==Container.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"     
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">     

<hibernate-mapping default-access="field">
  <class name="Container" table="Container">
    <id name="hibernateId" column="container_id">
      <generator class="native"/>
    </id>
    <any name="interf" meta-type="string" id-type="long">
        <column name="interf_type"/>
        <column name="interf_id"/>
    </any>
  </class>
</hibernate-mapping>

===Implementer.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"     
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">     

<hibernate-mapping default-access="field">
  <class name="Implementer" table="Implementer">
    <id name="hibernateId" column="implementer_id">
      <generator class="native"/>
    </id>
    <property name="value"/>
  </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():

Code:
import java.util.*;
import org.hibernate.*;

public class Test {

    public static void main(String[] args) {
        System.out.println(":::Isolation level is " +
                           System
                           .getProperty("hibernate.connection.isolation"));
        new Test().create();
        HibernateUtil.sessionFactory.close();
    }

    public void create() {
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        Container container = new Container();
        session.save(container);
        Implementer implementer = new Implementer();
        session.save(implementer);
        container.setInterface(implementer);
        tx.commit();
        tx = session.beginTransaction();
        Interface interf =
            (Interface)
            HibernateUtil.currentSession()
            .createQuery("from Interface")
            .list().iterator().next();
        System.out.println(":::Interface found======");
        interf.callOut();
        Iterator qqq =
            HibernateUtil.currentSession()
            .createQuery("from Container where interf = :i")
            .setParameter("i", interf)
            .list().iterator(); //FAILS IN THE LIST CALL
        while (qqq.hasNext()) {
            Container c = (Container)qqq.next();
            c.callOut();
        }
        tx.commit();
        HibernateUtil.closeSession();
    }
}

public class Container {

    public Container() {
    }

    public void setInterface(Interface i) {
        this.interf = i;
    }

    public void callOut() {
        System.out.println("Container:");
        System.out.print("  ");
        interf.callOut();
    }

    private long hibernateId;
    private Interface interf;

}

public interface Interface {

    public void callOut();

}

public class Implementer implements Interface {

    public Implementer() {
        value = (int)(Math.random()*100);
    }

    public void callOut() {
        System.out.println(":::Implementer #"+ value);
    }

    private int value;
    private long hibernateId;

}


Full stack trace of any exception that occurs:

Code:
10:24:12,682  INFO LongType:91 - could not bind value '16' to parameter: 2; The column index is out of range: 2, number of columns: 1.                         
10:24:12,694  WARN JDBCExceptionReporter:71 - SQL Error: 0, SQLState: 22023
10:24:12,699 ERROR JDBCExceptionReporter:72 - The column index is out of range: 2, number of columns: 1.
Exception in thread "main" org.hibernate.exception.DataException: could not execute query
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:77)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
        at org.hibernate.loader.Loader.doList(Loader.java:2148)
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2029)
        at org.hibernate.loader.Loader.list(Loader.java:2024)
        at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:392)
        at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:333)
        at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
        at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1123)
        at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
        at Test.create(Test.java:31)
        at Test.main(Test.java:10)
Caused by: org.postgresql.util.PSQLException: The column index is out of range: 2, number of columns: 1.
        at org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:38)
        at org.postgresql.core.v3.SimpleParameterList.setLiteralParameter(SimpleParameterList.java:68)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.bindLiteral(AbstractJdbc2Statement.java:2046)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.setLong(AbstractJdbc2Statement.java:1088)
        at org.hibernate.type.LongType.set(LongType.java:42)
        at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:83)
        at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:65)
        at org.hibernate.type.AnyType.nullSafeSet(AnyType.java:139)
        at org.hibernate.type.AnyType.nullSafeSet(AnyType.java:117)
        at org.hibernate.loader.hql.QueryLoader.bindNamedParameters(QueryLoader.java:515)
        at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1577)
        at org.hibernate.loader.Loader.doQuery(Loader.java:661)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
        at org.hibernate.loader.Loader.doList(Loader.java:2145)
        ... 9 more


Name and version of the database you are using: PostgreSQL 8.0.3

The generated SQL (show_sql=true):

select container0_.container_id as container1_0_, container0_.interf_type as interf2_0_, container0_.interf_id as interf3_0_ from Container container0_ where (container0_.interf_type, container0_.interf_id)=?

Debug level Hibernate log excerpt:

eh?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 06, 2006 5:28 pm 
Expert
Expert

Joined: Thu Sep 22, 2005 10:29 am
Posts: 285
Location: Almassera/Valencia/Spain/EU/Earth/Solar system/Milky Way/Local Group/Virgo Supercluster
you need several meta-values, don't you?

Code:
<meta-value value="TBL_ANIMAL" class="Animal"/>
<meta-value value="TBL_HUMAN" class="Human"/>
<meta-value value="TBL_ALIEN" class="Alien"/>

Code:
<meta-value value="CREDIT" class="CreditCardPayment"/>
<meta-value value="CASH" class="CashPayment"/>
<meta-value value="CHEQUE" class="ChequePayment"/>


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 07, 2006 8:17 pm 
Newbie

Joined: Fri Nov 11, 2005 1:34 pm
Posts: 5
From what I could read, the meta-value tags are optional; without them the database works properly, supplying the class/table name in that column as I expected, and the correct object pointed to with the "any" tag is retrieved when I traverse the objects. It's just the query that doesn't work. But hoping you might be right, I added a meta-value tag to my tiny example for the "any" tag, and that value was used instead, also as I expected, but the query still doesn't work.

I saw by googling that it's a common mistake when using Postgres to include bindings for string literals inside quotes:

http://www.slamb.org/projects/axamol/sql-library/manual/apa.html

Can anyone who knows more about how Hibernate sets up queries for postgres tell me if that's the issue? Or am I just still overlooking something obvious in my code?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 08, 2006 2:10 am 
Expert
Expert

Joined: Thu Sep 22, 2005 10:29 am
Posts: 285
Location: Almassera/Valencia/Spain/EU/Earth/Solar system/Milky Way/Local Group/Virgo Supercluster
try something like
Code:
from Container c where c.interf.class = 'Interface' and c.interf.id = :id

or
Code:
from Container c where c.interf.class = 'Implementer' and c.interf.id = :id


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 09, 2006 3:39 pm 
Newbie

Joined: Fri Nov 11, 2005 1:34 pm
Posts: 5
Thanks for trying to help, but still no good... The generated SQL reflects the change, but I still get the exact same error message.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 09, 2006 5:56 pm 
Expert
Expert

Joined: Thu Sep 22, 2005 10:29 am
Posts: 285
Location: Almassera/Valencia/Spain/EU/Earth/Solar system/Milky Way/Local Group/Virgo Supercluster
Which HQL?
and
Which generated SQL?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 12, 2006 11:33 am 
Newbie

Joined: Fri Nov 11, 2005 1:34 pm
Posts: 5
Absolutely *everything* involved-- all the source code, all the mapping files, all the error messages, all the hql, and all the SQL-- is already there in my first post. There's nothing else to it. It's very simple to reproduce. If anyone thinks it's relevant, the build file and hibernate.cfg.xml files are below. That is absolutely everything used to produce this exception.

Code:
====hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
                                                                               
<hibernate-configuration>
                                                                               
    <session-factory>
                                                                               
        <!-- Database connection settings -->
        <property name="connection.driver_class">org.postgresql.Driver</propert\y>
        <property name="connection.url">jdbc:postgresql:data</property>
        <property name="connection.username">postgres</property>
        <property name="connection.password"></property>
                                                                               
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
                                                                               
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</prope\rty>
                                                                               
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
                                                                               
        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>
                                                                               
        <mapping resource="Container.hbm.xml"/>
        <mapping resource="Implementer.hbm.xml"/>
                                                                               
    </session-factory>
                                                                               
</hibernate-configuration>

==build.xml
                                                                               
<project name="test" default="compile">
                                                                               
    <property name="sourcedir" value="${basedir}/src"/>
    <property name="targetdir" value="${basedir}/bin"/>
    <property name="librarydir" value="${basedir}/lib"/>
                                                                               
    <path id="libraries">
        <fileset dir="${librarydir}">
            <include name="*.jar"/>
        </fileset>
    </path>
                                                                               
    <target name="clean">
        <delete dir="${targetdir}"/>
        <mkdir dir="${targetdir}"/>
    </target>
                                                                               
    <target name="compile" depends="clean, copy-resources">
      <javac compiler="jikes"
             debug="yes"
             srcdir="${sourcedir}"
             destdir="${targetdir}"
             classpathref="libraries"/>
    </target>
                                                                               
    <target name="copy-resources">
        <copy todir="${targetdir}">
            <fileset dir="${sourcedir}">
                <exclude name="**/*.java"/>
            </fileset>
        </copy>
    </target>
                                                                               
  <target name="run" depends="compile">
    <java fork="true" classname="Test" classpathref="libraries">
        <classpath path="${targetdir}"/>
        <jvmarg value="-Dhibernate.connection.isolation=8"/>
        <jvmarg value="-Xdebug"/>
    </java>
  </target>
                                                                               
</project>
                                                                               
                                                                               


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