Problem Definition
We have defined a where clause on the <class name="A" table="A" where="ind = 'A'"> tag in the parent class.
B is a joined subclass of A. B has a one to one relationship to another class X.
If you look at the "on " condition for B you will notice that its using b1_1_.ind='A' which is the parent's alias which hasn't been defined yet.
Hence we get a invalid identifier error.
It looks like the generated query is faulty.
Has anyone come accross such a scenario? Am I doing something wrong?
I have reported this as a hibernate bug. URL is
http://opensource.atlassian.com/project ... tion_32854
Hibernate version:3.2.2
Name and version of the database you are using:
Oracle 10g
Mapping documents:
A.hbm
<?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 package="hibernate">
<class name="A" table="A" where="ind = 'A'">
<id name="id" type="long" column="ID">
<generator class="sequence">
<param name="sequence">CATEGORY_SEQ</param>
</generator>
</id>
<property name="ind" column="IND" not-null="true" type="string" />
<joined-subclass extends="A" name="B">
<key column="id"></key>
<many-to-one name="x" column="X_ID" class="X" unique="true"></many-to-one>
</joined-subclass>
</class>
</hibernate-mapping>
X.hbm
<?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 package="hibernate">
<class name="X" table="X" where="ind = 'A'">
<id name="id" type="long" column="ID">
<generator class="sequence">
<param name="sequence">BID_SEQ</param>
</generator>
</id>
<property name="ind" column="IND" not-null="true" type="string" />
<one-to-one name="b" property-ref="x" constrained="false"></one-to-one>
<!--
<set name="bs" inverse="false">
<key column="x_id"></key>
<one-to-many class="B"/>
</set>
--></class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
SessionFactory sessionFactory = config.buildSessionFactory();
Session s = sessionFactory.getCurrentSession();
Transaction t = s.beginTransaction();
String query = "from X x left join x.b bac1";
//s.get(X.class, 1L);
s.createQuery(query).list();
t.commit();
Full stack trace of any exception that occurs:
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.loader.Loader.doList(Loader.java:2214)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095)
at org.hibernate.loader.Loader.list(Loader.java:2090)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:375)
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 hibernate.TestHibernate.main(TestHibernate.java:29)
Caused by: java.sql.SQLException: ORA-00904: "B1_1_"."IND": invalid identifier
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:799)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1038)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:839)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1133)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3329)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1778)
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:2211)
... 8 more
The generated SQL (show_sql=true):
Hibernate:
/*
from
X x
left join
x.b bac1 */ select
x0_.ID as ID2_0_,
b1_.id as ID0_1_,
x0_.IND as IND2_0_,
b1_1_.IND as IND0_1_,
b1_.X_ID as X2_1_1_
from
X x0_
left outer join
B b1_
on x0_.ID=b1_.X_ID
and (
b1_1_.ind = 'A'
)
left outer join
A b1_1_
on b1_.id=b1_1_.ID
where
(
x0_.ind = 'A'
)
script for tables
create table A (
id number primary key,
ind char(1)
);
create table X (
id number primary key,
ind char(1)
);
create table B(
id number primary key,
ind char(1),
x_id number
);
ALTER TABLE B
ADD CONSTRAINT B_A_FK1 FOREIGN KEY
(
"ID"
) REFERENCES TEST.A
(
"ID"
) ENABLE
;
ALTER TABLE B
ADD CONSTRAINT B_X_FK1 FOREIGN KEY
(
"X_ID"
) REFERENCES TEST.X
(
"ID"
) ENABLE
;