I am following an example that appears in hibernate tutorial Point 7.6. It generates a faulty SQL code. I don't know if it is a bug or I am doing something wrong
The version data is:
Quote:
Hibernate version: 3.2.5 ga
Name and version of the database: mysql-5.0.45-win32
Driver: com.mysql.jdbc.Driver
Dialect: org.hibernate.dialect.MySQLDialect
Debug level Hibernate log excerpt: INFO
The mapping documents are:
Quote:
<?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="account" schema="accounts">
<class name="Account">
<id name="id">
<generator class="native" />
</id>
<properties name="currentAccountKey">
<property name="accountNumber" type="string" not-null="true"/>
<property name="currentAccount" type="boolean" formula="case when effectiveEndDate is null then 1 else 0 end" />
</properties>
<property name="effectiveEndDate" type="date"/>
<property name="effectiveStateDate" type="date" not-null="true"/>
</class>
<class name="Client">
<id name="id">
<generator class="native" />
</id>
<many-to-one name="currentAccountInfo"
property-ref="currentAccountKey"
class="Account">
<column name="accountNumber" />
<formula>'1'</formula>
</many-to-one>
</class>
</hibernate-mapping>
I create and save 2 Account objects and a Client. Then I commit transaction. Everything goes right till that moment. The problem is in the generated SQL code that gets the Client from the database: (Client) sesion.createQuery("from Client").uniqueResult()
I use the following code:
Quote:
Session sesion = HibernateUtil.getSessionFactory().openSession();
sesion.beginTransaction();
Account account = new Account();
account.setAccountNumber("12345678");
account.setEffectiveStateDate(new Date());
sesion.save(account);
Account oldAccount = new Account();
oldAccount.setAccountNumber("12345678");
oldAccount.setEffectiveStateDate(new Date());
oldAccount.setEffectiveEndDate(new Date());
sesion.save(oldAccount);
Client cliente = new Client();
cliente.setCurrentAccountInfo(account);
sesion.save(cliente);
sesion.getTransaction().commit();
sesion = HibernateUtil.getSessionFactory().openSession();
sesion.beginTransaction();
cliente = (Client) sesion.createQuery("from Client").uniqueResult();
System.out.println("Fecha fin: " + cliente.getCurrentAccountInfo().getEffectiveEndDate());
sesion.getTransaction().commit();
It happens de following exception. You may see that the end of the query is: and account0_.null=?
Quote:
Hibernate: select account0_.id as id8_0_, account0_.accountNumber as accountN2_8_0_, account0_.effectiveEndDate as effectiv3_8_0_, account0_.effectiveStateDate as effectiv4_8_0_, case when account0_.effectiveEndDate is null then 1 else 0 end as formula0_0_ from accounts.Account account0_ where account0_.accountNumber=? and account0_.null=?
13:04:43,062 WARN JDBCExceptionReporter:77 - SQL Error: 1054, SQLState: 42S22
13:04:43,062 ERROR JDBCExceptionReporter:78 - Unknown column 'account0_.null' in 'where clause'
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not load an entity: [account.Account#component[accountNumber,currentAccount]{accountNumber=12345678, currentAccount=true}]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1874)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
at org.hibernate.loader.entity.EntityLoader.loadByUniqueKey(EntityLoader.java:85)
at org.hibernate.persister.entity.AbstractEntityPersister.loadByUniqueKey(AbstractEntityPersister.java:1645)
at org.hibernate.type.EntityType.loadByUniqueKey(EntityType.java:608)
at org.hibernate.type.EntityType.resolve(EntityType.java:382)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:116)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:854)
at org.hibernate.loader.Loader.doQuery(Loader.java:729)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2220)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
at org.hibernate.loader.Loader.list(Loader.java:2099)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)
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 org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:811)
at account.Main.main(Main.java:39)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'account0_.null' in 'where clause'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1031)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3376)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3308)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1837)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1961)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2543)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1737)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1888)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
at org.hibernate.loader.Loader.doQuery(Loader.java:674)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1860)
... 19 more
The generated SQL is:
Quote:
select account0_.id as id8_0_, account0_.accountNumber as accountN2_8_0_, account0_.effectiveEndDate as effectiv3_8_0_, account0_.effectiveStateDate as effectiv4_8_0_, case when account0_.effectiveEndDate is null then 1 else 0 end as formula0_0_ from accounts.Account account0_ where account0_.accountNumber=? and account0_.null=?
And it should be:
Quote:
The generated SQL is:
select account0_.id as id8_0_, account0_.accountNumber as accountN2_8_0_, account0_.effectiveEndDate as effectiv3_8_0_, account0_.effectiveStateDate as effectiv4_8_0_, case when account0_.effectiveEndDate is null then 1 else 0 end as formula0_0_ from accounts.Account account0_ where account0_.accountNumber=? and (case when account0_.effectiveEndDate is null then 1 else 0 end)=?
Problem seems to happen, because <formula>'1'</formula>, refers to a property which is formula generated, and not persisted in a database column.