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