This may be a trivial issue that I am overlooking. I have a saveOrUpdate() being wrapped in a net.sf.hibernate.Transaction object. There is a one-to-one relationship between my Order object and the PaymentInformation object. The authorizationCode in the PaymentInformation is required and since it is not present, I encounter an exception, which is the desired behavior. However, when I call rollback, the Order object does not get rolled back and is inserted into the DB. I have done something very similar in terms of transaction handling with SAPDB and not had problems. This is the first time I have done a one-to-one mapping and I don't know if it is because of my one-to-one mapping or something to do with MySQL4.1.
Any help is greatly appreciated.
Hibernate version:2.1.4
Mapping documents:
Code:
<hibernate-mapping>
<class name="com.gpani.commerce.paytrust.beans.order.Order" table="ORDERS" dynamic-update="false" dynamic-insert="false">
<id name="orderId" column="ORDERID" type="java.lang.Long" unsaved-value="null">
<generator class="native"></generator>
</id>
<one-to-one name="paymentInformation" class="com.gpani.commerce.paytrust.beans.order.PaymentInformation" cascade="save-update" outer-join="auto" constrained="false"/>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.gpani.commerce.paytrust.beans.order.PaymentInformation" table="PAYMENTINFORMATIONS" dynamic-update="false" dynamic-insert="false">
<id name="orderId" column="ORDERID" type="java.lang.Long" unsaved-value="null">
<generator class="foreign">
<param name="property">order</param>
</generator>
</id>
<one-to-one name="order" class="com.gpani.commerce.paytrust.beans.order.Order" cascade="none" outer-join="auto" constrained="false"/>
<property name="cardHolderName" type="java.lang.String" update="false" insert="true" column="CARDHOLDERNAME" not-null="true"/>
<property name="creditCardNumber" type="java.lang.String" update="false" insert="true" column="CREDITCARDNUMBER" not-null="true"/>
<property name="authorizationCode" type="java.lang.String" update="false" insert="true" column="AUTHORIZATIONCODE" not-null="true"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
try
{
hibernateSession = HibernateManager.currentSession();
transaction = hibernateSession.beginTransaction();
order.getPaymentInformation();
paymentInformation.setCreditCardNumber(Utilities.maskCreditCardNumber(paymentInformation.getCreditCardNumber()));
order.setPaymentInformation(paymentInformation);
hibernateSession.saveOrUpdate(order);
transaction.commit();
saved = true;
}
catch (Exception e)
{
try
{
logger.debug("begin rollback");
transaction.rollback();
logger.debug("end rollback");
}
catch (Exception ex)
{
logger.warn("Exception encountered rolling back transaction due to General Exception in " + sMethodName + Utilities.getStackTrace(ex));
}
logger.warn("Exception in " + sMethodName + Utilities.getStackTrace(e));
}
finally
{
if (hibernateSession != null)
{
try
{
hibernateSession.close();
}
catch (HibernateException e)
{
logger.warn("Hibernate Exception closing session in " + sMethodName + Utilities.getStackTrace(e));
}
}
}
Full stack trace of any exception that occurs:Code:
WARN [com.gpani.commerce.paytrust.dao.order.OrderDAO] - Exception in save(com.gpani.commerce.paytrust.beans.order.Order@17e4c97):
Stack Trace:
net.sf.hibernate.PropertyValueException: not-null property references a null or transient value: com.gpani.commerce.paytrust.beans.order.PaymentInformation.authorizationCode
at net.sf.hibernate.impl.SessionImpl.checkNullability(SessionImpl.java:1276)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:928)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:857)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:779)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:738)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1387)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:951)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:857)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:775)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:738)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1387)
at com.gpani.commerce.paytrust.dao.order.OrderDAO.save(Unknown Source)
at com.gpani.commerce.paytrust.control.site.transaction.CompleteTransactionAction.view(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
Name and version of the database you are using:MySQL 4.1Debug level Hibernate log excerpt:Code:
DEBUG net.sf.hibernate.impl.SessionImpl - opened session
DEBUG net.sf.hibernate.transaction.JDBCTransaction - begin
DEBUG net.sf.hibernate.transaction.JDBCTransaction - current autocommit status:true
DEBUG net.sf.hibernate.transaction.JDBCTransaction - disabling autocommit
DEBUG net.sf.hibernate.impl.SessionImpl - saveOrUpdate() unsaved instance
DEBUG net.sf.hibernate.impl.SessionImpl - saving [com.gpani.commerce.paytrust.beans.order.Order#<null>]
DEBUG net.sf.hibernate.impl.SessionImpl - executing insertions
DEBUG net.sf.hibernate.engine.Cascades - processing cascades for: com.gpani.commerce.paytrust.beans.order.Order
DEBUG net.sf.hibernate.engine.Cascades - done processing cascades for: com.gpani.commerce.paytrust.beans.order.Order
DEBUG net.sf.hibernate.impl.WrapVisitor - Wrapped collection in role: com.gpani.commerce.paytrust.beans.order.Order.assignedEntityValueList
DEBUG net.sf.hibernate.engine.Cascades - id unsaved-value strategy NULL
DEBUG net.sf.hibernate.persister.EntityPersister - Inserting entity: com.gpani.commerce.paytrust.beans.order.Order (native id)
DEBUG net.sf.hibernate.impl.BatcherImpl - about to open: 0 open PreparedStatements, 0 open ResultSets
DEBUG net.sf.hibernate.SQL - insert into ORDERS (TRANSACTIONTYPEID, PAYMENTTOTAL, SERVICEFEE, IPADDRESS, EMAIL, UPDATEON) values (?, ?, ?, ?, ?, ?)
DEBUG net.sf.hibernate.impl.BatcherImpl - preparing statement
DEBUG net.sf.hibernate.persister.EntityPersister - Dehydrating entity: [com.gpani.commerce.paytrust.beans.order.Order#<null>]
DEBUG net.sf.hibernate.engine.Cascades - id unsaved-value strategy NULL
DEBUG net.sf.hibernate.type.LongType - binding '1' to parameter: 1
DEBUG net.sf.hibernate.type.DoubleType - binding '25000.0' to parameter: 2
DEBUG net.sf.hibernate.type.DoubleType - binding '687.5' to parameter: 3
DEBUG net.sf.hibernate.type.StringType - binding '127.0.0.1' to parameter: 4
DEBUG net.sf.hibernate.type.StringType - binding 'foo@bar.com' to parameter: 5
DEBUG net.sf.hibernate.type.TimestampType - binding null to parameter: 6
DEBUG net.sf.hibernate.persister.AbstractEntityPersister - Natively generated identity: 46
DEBUG net.sf.hibernate.impl.BatcherImpl - done closing: 0 open PreparedStatements, 0 open ResultSets
DEBUG net.sf.hibernate.impl.BatcherImpl - closing statement
DEBUG net.sf.hibernate.engine.Cascades - processing cascades for: com.gpani.commerce.paytrust.beans.order.Order
DEBUG net.sf.hibernate.engine.Cascades - cascading to saveOrUpdate()
DEBUG net.sf.hibernate.impl.SessionImpl - saveOrUpdate() unsaved instance
DEBUG net.sf.hibernate.impl.SessionImpl - generated identifier: 46
DEBUG net.sf.hibernate.impl.SessionImpl - saving [com.gpani.commerce.paytrust.beans.order.PaymentInformation#46]
DEBUG net.sf.hibernate.transaction.JDBCTransaction - rollback
DEBUG net.sf.hibernate.impl.SessionImpl - transaction completion
DEBUG net.sf.hibernate.transaction.JDBCTransaction - re-enabling autocommit
DEBUG net.sf.hibernate.impl.SessionImpl - closing session
DEBUG net.sf.hibernate.impl.SessionImpl - disconnecting session
DEBUG net.sf.hibernate.impl.SessionImpl - transaction completion
DEBUG net.sf.hibernate.impl.SessionImpl - closing session