-->
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.  [ 1 post ] 
Author Message
 Post subject: Missing column when doing insert with formula attribute
PostPosted: Mon Jun 25, 2007 5:29 am 
Newbie

Joined: Mon Jun 25, 2007 3:43 am
Posts: 1
Background:
Our application uses a "subclass-per-table"-hierarchy. The superclass, called LogRecords, holds a discriminator column. The application consists of two, standalone, parts: one which logs data to the database and one which reads data from the database. The reading part may use a different version of the mapping files than the logging part.

For example, the logging part uses version 3 of the mapping files containing subclasses "a","b" and "c" whereas the reading part uses version 2 of the mapping files which only contains definitions of subclasses "a" and "b".

Problem:
We recently added a formula attribute in the discriminator tag in order to make the "reading" part of the application able to handle subclasses that had no definition in its mapping file. Previously, Hibernate would throw an exception if it found subclass "c" which was not defined in the mapping files. This behaviour is natural, so we introduced a formula attribute in the discriminator part that states that if the subclass belongs to a set of "unknown" subclasses, then treat it as a superclass:

    <hibernate-mapping package="se.micronic.milou.model">
    <class table="logrecords" discriminator-value="0" name="LogRecord" node="logrecord">
    <id column="logrecord_id" name="logRecordId" node="@id"></id>
    <discriminator column="subclass_table" formula="case when subclass_table in ('1','2','3') then '0' else subclass_table end"/>
    ...

This works fine when using selects. However, when using inserts, Hibernate generates an unexpected JDBC insert: it simply excludes the discriminator column from the insert, which generates an JDBC exception:

    2007-06-25 00:17:54.671 DEBUG org.hibernate.SQL log select logrecord0_.logrecord_id as logrecord1_15_0_, logrecord0_.dbtime as dbtime15_0_, logrecord0_.parentlogrecord_id as parentlo3_15_0_, logrecord0_.logrecordtype_id as logrecor4_15_0_, logrecord0_.logtime as logtime15_0_, case when logrecord0_.subclass_table in ('1','2','3') then '0' else logrecord0_.subclass_table end as clazz_0_ from logrecords logrecord0_ where logrecord0_.logrecord_id=?

    // The insert does not contain the subclass_table column, which leads to the error below
    2007-06-25 00:17:54.686 DEBUG org.hibernate.SQL log insert into logrecords (dbtime, parentlogrecord_id, logrecordtype_id, logtime, logrecord_id) values (?, ?, ?, ?, ?)

    2007-06-25 00:17:54.733 WARN org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 1364, SQLState: HY000
    2007-06-25 00:17:54.733 ERROR org.hibernate.util.JDBCExceptionReporter logExceptions Field 'subclass_table' doesn't have a default value

The same scenario without the formula attribute generates a correct insert statement which works fine:

    2007-06-25 00:07:00.773 DEBUG org.hibernate.SQL log select logrecord0_.logrecord_id as logrecord1_1_0_, logrecord0_.dbtime as dbtime1_0_, logrecord0_.parentlogrecord_id as parentlo4_1_0_, logrecord0_.logrecordtype_id as logrecor5_1_0_, logrecord0_.logtime as logtime1_0_, logrecord0_.subclass_table as subclass2_1_0_ from logrecords logrecord0_ where logrecord0_.logrecord_id=?

    // Note that the subclass_table column is present
    2007-06-25 00:07:00.804 DEBUG org.hibernate.SQL log insert into logrecords (dbtime, parentlogrecord_id, logrecordtype_id, logtime, subclass_table, logrecord_id) values (?, ?, ?, ?, '60501', ?)

We don't understand why the formula attribute in the discriminator tag makes Hibernate behave this way. Should we have defined the formula in a different way, or is there any other workaround?

We would be grateful for any help.


Hibernate version: 3.2.2.ra

Mapping documents:
    <hibernate-mapping package="se.micronic.milou.model">
    <class table="logrecords" discriminator-value="0" name="LogRecord" node="logrecord">
    <id column="logrecord_id" name="logRecordId" node="@id">
    </id>
    <discriminator column="subclass_table" formula="case when subclass_table in ('1','2','3','64601','64602','64603','64701','64702','64703','64801','64802','64803','64901','64902','64903','65001','65002','65003','65101','65102','65103','65201','65202','65203','65301','65302','65303','65401','65402','65403','65501','65502','65503','65601','65602','65603','65701','65702','65703','65801','65802','65803','65901','65902','65903','66001','66002','66003','66101','66102','66103','66500','66201','66202','66203','66301','66302','66303','66401','66402','66403') then '0' else subclass_table end"/>
    <timestamp name="dbtime" node="dbtime"/>
    <many-to-one class="LogRecord" column="parentlogrecord_id" name="parentLogrecord" node="parentlogrecord"/>
    <many-to-one class="LogRecordType" column="logrecordtype_id" name="logRecordType" lazy="false" fetch="select" node="logrecordtype"/>
    <property not-null="true" name="logtime" node="logtime"/>
    <set cascade="all" name="userComments" lazy="true">
    <key column="logrecord_id"/>
    <one-to-many class="Comment"/>
    </set>
    </class>
    <subclass extends="se.micronic.milou.model.LogRecord" discriminator-value="1" name="LogRecordRootStartAct">
    <join fetch="select" table="rootstartact">
    <key column="logrecord_id"/>
    <property name="name" column="_name"/>
    </join>
    </subclass>
    <subclass extends="se.micronic.milou.model.LogRecord" discriminator-value="2" name="LogRecordRootEndActOk">
    <join fetch="select" table="rootendactok">
    <key column="logrecord_id"/>
    </join>
    </subclass>
    <subclass extends="se.micronic.milou.model.LogRecord" discriminator-value="3" name="LogRecordRootEndActFail">
    <join fetch="select" table="endactfail">
    <key column="logrecord_id"/>
    </join>
    </subclass>
    </hibernate-mapping>

Full stack trace of any exception that occurs:
    2007-06-25 08:45:06.752 DEBUG org.hibernate.SQL log select logrecord0_.logrecord_id as logrecord1_1_0_, logrecord0_.dbtime as dbtime1_0_, logrecord0_.parentlogrecord_id as parentlo3_1_0_, logrecord0_.logrecordtype_id as logrecor4_1_0_, logrecord0_.logtime as logtime1_0_, case when logrecord0_.subclass_table in ('1','2','3','64601','64602','64603','64701','64702','64703','64801','64802','64803','64901','64902','64903','65001','65002','65003','65101','65102','65103','65201','65202','65203','65301','65302','65303','65401','65402','65403','65501','65502','65503','65601','65602','65603','65701','65702','65703','65801','65802','65803','65901','65902','65903','66001','66002','66003','66101','66102','66103','66500','66201','66202','66203','66301','66302','66303','66401','66402','66403') then '0' else logrecord0_.subclass_table end as clazz_0_ from logrecords logrecord0_ where logrecord0_.logrecord_id=?

    2007-06-25 08:45:06.767 DEBUG org.hibernate.SQL log insert into logrecords (dbtime, parentlogrecord_id, logrecordtype_id, logtime, logrecord_id) values (?, ?, ?, ?, ?)

    2007-06-25 08:45:06.814 WARN org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 1364, SQLState: HY000

    2007-06-25 08:45:06.830 ERROR org.hibernate.util.JDBCExceptionReporter logExceptions Field 'subclass_table' doesn't have a default value

    2007-06-25 08:45:06.845 ERROR org.hibernate.event.def.AbstractFlushingEventListener performExecutions Could not synchronize database state with sessionorg.hibernate.exception.GenericJDBCException Could not execute JDBC batch update org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update

    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.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)

    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:92)

    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)

    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2228)

    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2656)

    at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:52)

    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)

    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)

    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)

    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)

    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)

    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)

    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)

    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)

    at se.micronic.milou.gui.dataaccess.hibernate.LogRecordManipulationDao$1.onEnd(LogRecordManipulationDao.java:309)

    at org.dom4j.io.DispatchHandler.onEnd(DispatchHandler.java:202)

    at org.dom4j.io.SAXContentHandler.endElement(SAXContentHandler.java:268)

    at org.apache.xerces.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:579)

    at org.apache.xerces.impl.XMLNamespaceBinder.handleEndElement(XMLNamespaceBinder.java:897)

    at org.apache.xerces.impl.XMLNamespaceBinder.endElement(XMLNamespaceBinder.java:643)

    at org.apache.xerces.impl.dtd.XMLDTDValidator.handleEndElement(XMLDTDValidator.java:1972)

    at org.apache.xerces.impl.dtd.XMLDTDValidator.endElement(XMLDTDValidator.java:878)

    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.handleEndElement(XMLDocumentFragmentScannerImpl.java:1144)

    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:987)

    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(XMLDocumentFragmentScannerImpl.java:1445)

    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:333)

    at org.apache.xerces.parsers.DTDConfiguration.parse(DTDConfiguration.java:524)

    at org.apache.xerces.parsers.DTDConfiguration.parse(DTDConfiguration.java:580)

    at org.apache.xerces.parsers.XMLParser.parse(XMLParser.java:152)

    at org.apache.xerces.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1169)

    at org.dom4j.io.SAXReader.read(SAXReader.java:465)

    at org.dom4j.io.SAXReader.read(SAXReader.java:365)

    at se.micronic.milou.gui.dataaccess.hibernate.LogRecordManipulationDao.parseXmlDoc(LogRecordManipulationDao.java:343)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

    at java.lang.reflect.Method.invoke(Unknown Source)

    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:292)

    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:163)

    at $Proxy4.parseXmlDoc(Unknown Source)

    at se.micronic.milou.gui.web.beans.AdministrationProvider.importFiles(AdministrationProvider.java:121)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

    at java.lang.reflect.Method.invoke(Unknown Source)

    at org.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:129)

    at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:63)

    at javax.faces.component.UICommand.broadcast(UICommand.java:106)

    at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:94)

    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:168)

    at org.apache.myfaces.lifecycle.LifecycleImpl.invokeApplication(LifecycleImpl.java:343)

    at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:86)

    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:137)

    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)

    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)

    at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144)

    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)

    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)

    at se.micronic.milou.gui.web.security.NewSecurityFilter.doFilter(NewSecurityFilter.java:49)

    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)

    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)

    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)

    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)

    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)

    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)

    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)

    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)

    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)

    at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)

    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)

    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)

    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)

    at java.lang.Thread.run(Unknown Source)

    Caused by: java.sql.BatchUpdateException: Field 'subclass_table' doesn't have a default value

    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1213)

    at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:912)

    at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:205)

    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)

    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)

    ... 72 more


Name and version of the database you are using:
MySql 5.0
MySql 5.0mysql-connector (jdbc-driver) 5.0.5

The generated SQL (show_sql=true):
    2007-06-25 11:15:27.136 DEBUG org.hibernate.SQL log select logrecord0_.logrecord_id as logrecord1_1_0_, logrecord0_.dbtime as dbtime1_0_, logrecord0_.parentlogrecord_id as parentlo3_1_0_, logrecord0_.logrecordtype_id as logrecor4_1_0_, logrecord0_.logtime as logtime1_0_, case when logrecord0_.subclass_table in ('1','2','3','64601','64602','64603','64701','64702','64703','64801','64802','64803','64901','64902','64903','65001','65002','65003','65101','65102','65103','65201','65202','65203','65301','65302','65303','65401','65402','65403','65501','65502','65503','65601','65602','65603','65701','65702','65703','65801','65802','65803','65901','65902','65903','66001','66002','66003','66101','66102','66103','66500','66201','66202','66203','66301','66302','66303','66401','66402','66403') then '0' else logrecord0_.subclass_table end as clazz_0_ from logrecords logrecord0_ where logrecord0_.logrecord_id=?

    2007-06-25 11:15:27.136 DEBUG org.hibernate.type.LongType nullSafeSet binding '1495001' to parameter: 1

    2007-06-25 11:15:27.152 DEBUG org.hibernate.type.StringType nullSafeGet returning '46601' as column: clazz_0_

    2007-06-25 11:15:27.152 DEBUG org.hibernate.type.TimestampType nullSafeGet returning '2007-03-21 15:15:46' as column: dbtime1_0_

    2007-06-25 11:15:27.152 DEBUG org.hibernate.type.LongType nullSafeGet returning null as column: parentlo3_1_0_

    2007-06-25 11:15:27.152 DEBUG org.hibernate.type.IntegerType nullSafeGet returning '46601' as column: logrecor4_1_0_

    2007-06-25 11:15:27.152 DEBUG org.hibernate.type.LongType nullSafeGet returning '1174486508335' as column: logtime1_0_

    2007-06-25 11:15:27.167 DEBUG org.hibernate.SQL log insert into logrecords (dbtime, parentlogrecord_id, logrecordtype_id, logtime, logrecord_id) values (?, ?, ?, ?, ?)

    2007-06-25 11:15:27.167 DEBUG org.hibernate.type.TimestampType nullSafeSet binding '2007-06-25 11:15:27' to parameter: 1

    2007-06-25 11:15:27.167 DEBUG org.hibernate.type.LongType nullSafeSet binding '1495001' to parameter: 2

    2007-06-25 11:15:27.183 DEBUG org.hibernate.type.IntegerType nullSafeSet binding '60501' to parameter: 3

    2007-06-25 11:15:27.183 DEBUG org.hibernate.type.LongType nullSafeSet binding '1174486691597' to parameter: 4

    2007-06-25 11:15:27.183 DEBUG org.hibernate.type.LongType nullSafeSet binding '1495620' to parameter: 5

    2007-06-25 11:15:27.246 WARN org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 1364, SQLState: HY000

    2007-06-25 11:15:27.246 ERROR org.hibernate.util.JDBCExceptionReporter logExceptions Field 'subclass_table' doesn't have a default value







Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

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.