-->
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.  [ 3 posts ] 
Author Message
 Post subject: Hibernate overwriting field value during flush() ?
PostPosted: Thu Feb 18, 2010 1:15 pm 
Newbie

Joined: Thu Feb 18, 2010 12:49 pm
Posts: 1
Hi

I have a strange problem where hibernate seems to be overwriting a field in a DTO object during the session.flush()

I am using hibernate 3.2.7 and Oracle JDBC driver 10.2.0.1.0

When I call session.flush() to write data to the database, I get an exception, with this as the root cause:

Caused by: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("PINTPRO"."TRM_RMA_AUTHORISATION"."USER_LAST_CHANGED")

The exception only happens when using Oracle - not with DB2, and even then only occurs intermittently - perhaps once in every 4 or 5 attempts.

Here's an extract of the code, all of which is called witin the scope of a JTA transaction started earlier:

Code:
public static boolean storeAuthorisation(
      Integer sequenceNo, String bankID, String bicPlusIssuer,
      String bicPlusCorrespondent, String swiftServiceCode,
      String directionCode, java.sql.Timestamp issuedTime,
      java.util.Date fromDate, java.util.Date toDate, String statusCode,
      String lockIndicator, String signature ,String userLastChanged,
      Collection permission, Timestamp dateLastChanged, UserProfile userProfile) throws DAOException {

   Session session = ResourcesLocator.getHibernateSessionFactory().openSession(new AuditInterceptor(userProfile.getBankId(), userProfile.getUserId()));
      
   // Create authorisation dto object            
   TrmRmaAuthorisation dto = new TrmRmaAuthorisation();
   dto.setAuthoSequenceNo(sequenceNo);

   // Set owning bank (use dummy DTO object with only ID set)
   TrmBank trmBank = new TrmBank();
   trmBank.setBankId(bankID); 
   dto.setTrmBank(trmBank);
   
   // ... lines omitted, populating fields of dto ...

   // Set user last changed
   dto.setUserLastChanged(userLastChanged);
   
   try {
      session.save(dto);
   
      // DEBUG LOGGING
      String str = "userLastChanged: " +
         ((TrmRmaAuthorisation)session.get(TrmRmaAuthorisation.class, dto.getAuthoSequenceNo())).getUserLastChanged();
      logger.log(Level.DEBUG, str);
   
      session.flush();
      session.close();


As you can see, I call dto.setUserLastChanged(), and I know that the value I am setting is not null - see first line of the log output below. But somehow, it seems that during the flush, hibernate has overwritten, or lost the value. Here's an extract from the log:

2010-02-18 17:56:34,953 DEBUG(AuthorisationManagerDAO.java:662) - userLastChanged: JED
2010-02-18 17:56:35,546 ERROR(AuthorisationManagerDAO.java:673) - Could not execute JDBC batch update
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:254)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
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:1001)
at com.te.rma.ejb.helpers.dao.AuthorisationManagerDAO.storeAuthorisation(AuthorisationManagerDAO.java:663)
at com.te.rma.ejb.helpers.businesslogic.AuthorisationManagerBL.issueAuthorisation(AuthorisationManagerBL.java:349)
at com.te.rma.ejb.authorisationmanager.AuthorisationManagerBean.issueAuthorisation(AuthorisationManagerBean.java:62)
at com.te.rma.ejb.authorisationmanager.EJSLocalStatelessAuthorisationManager_bb2d9c86.issueAuthorisation(Unknown Source)
at com.te.rma.bdelegate.AuthorisationManagerImpl.issueAuthorisation(AuthorisationManagerImpl.java:55)
at com.te.rma.ui.servlet.action.authorisationDetails.IssueAuthorisationAction.doBusinessLogic(IssueAuthorisationAction.java:172)
at com.te.rma.ui.servlet.action.Action.execute(Action.java:180)
at com.te.rma.ui.servlet.controller.Controller.doPost(Controller.java:105)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:763)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1146)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:592)
at com.ibm.ws.wswebcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:481)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:90)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:748)
at com.ibm.ws.wswebcontainer.WebContainer.handleRequest(WebContainer.java:1466)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:122)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:458)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:387)
at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:102)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:136)
at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:196)
at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:751)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)
Caused by: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("PINTPRO"."TRM_RMA_AUTHORISATION"."USER_LAST_CHANGED")

at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10656)
at com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.pmiExecuteBatch(WSJdbcPreparedStatement.java:941)
at com.ibm.ws.rsadapter.jdbc.WSJdbcStatement.executeBatch(WSJdbcStatement.java:705)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:247)
... 33 more


The weird thing is, that this only occurs intermittently - maybe one in every 4 or 5 attemps.

The DTO object I am writing to write to the DB is generated using hbm2java. The hbm file is as follows:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 19.aug.2006 17:30:44 by Hibernate Tools 3.1.0 beta1JBIDERC2 -->
<hibernate-mapping>
    <class name="com.te.rma.hibernate.TrmRmaAuthorisation" table="TRM_RMA_AUTHORISATION">
        <id name="authoSequenceNo" type="integer">
            <column name="AUTHO_SEQUENCE_NO" />
            <generator class="assigned" />
        </id>
        <many-to-one name="trmBank" class="com.te.rma.hibernate.TrmBank" fetch="select">
            <column name="BANK_ID" length="4" not-null="true" />
        </many-to-one>
        <property name="bicplIssuer" type="string">
            <column name="BICPL_ISSUER" length="8" not-null="true" />
        </property>
        <property name="bicplCorresponden" type="string">
            <column name="BICPL_CORRESPONDEN" length="8" not-null="true" />
        </property>
        <property name="swserServiceCode" type="string">
            <column name="SWSER_SERVICE_CODE" length="11" not-null="true" />
        </property>
        <property name="audirCode" type="string">
            <column name="AUDIR_CODE" length="8" not-null="true" />
        </property>
        <property name="authoIssuedTime" type="timestamp">
            <column name="AUTHO_ISSUED_TIME" length="26" />
        </property>
        <property name="authoFromDate" type="date">
            <column name="AUTHO_FROM_DATE" length="10" />
        </property>
        <property name="authoToDate" type="date">
            <column name="AUTHO_TO_DATE" length="10" />
        </property>
        <property name="austaStatusCode" type="string">
            <column name="AUSTA_STATUS_CODE" length="8" not-null="true" />
        </property>
        <property name="authoLockIndic" type="character">
            <column name="AUTHO_LOCK_INDIC" length="1" not-null="true" />
        </property>
        <property name="authoSignature" type="string">
            <column name="AUTHO_SIGNATURE" length="1000" />
        </property>
        <property name="userLastChanged" type="string">
            <column name="USER_LAST_CHANGED" length="8" not-null="true" />
        </property>
        <property name="dateLastChanged" type="timestamp">
            <column name="DATE_LAST_CHANGED" length="26" not-null="true" />
        </property>
        <set name="trmRmaAuthorisationPermissions" inverse="true">
            <key>
                <column name="AUTHO_SEQUENCE_NO" not-null="true" />
            </key>
            <one-to-many class="com.te.rma.hibernate.TrmRmaAuthorisationPermission" />
        </set>
    </class>
</hibernate-mapping>


Any idea what can be happening?


Thanks

Matthew


Top
 Profile  
 
 Post subject: Re: Hibernate overwriting field value during flush() ?
PostPosted: Thu Feb 18, 2010 5:10 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Is the value an empty string? If so, Oracle will automatically convert it to null. Oracle doesn't support empty strings.


Top
 Profile  
 
 Post subject: Re: Hibernate overwriting field value during flush() ?
PostPosted: Fri Feb 19, 2010 2:31 am 
Newbie

Joined: Fri Feb 19, 2010 2:23 am
Posts: 1
No, The userLastchange is not empty, Please see the first line of the code the userLastchanged is JED and this is the statement logged after session.save()


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