Search code examples
hibernatestruts-1

struts 1 throws org.hibernate.TransientObjectException


I am trying to add activity auditing to my struts 1 application. I change an object and then I want to create a row in my auditing table that refers to the changed object. I am getting TransientObjectException because I've changed the referent object. I tried flushing the session, but that didn't solve it and I'm not sure why.

merchant.setTrusted(false);
merchantDAO.saveOrUpdate(merchant);
// trying to resolve org.hibernate.PropertyValueException: not-null property references a null or transient value: com.rc.model.ActivityAudit.user
SessionManagerFactory.getSessionManager(DatasourceType.M).getSession().flush();

ActivityAuditManager.addActivityAudit("Set merchant to untrusted", merchant, userAccount);

where ActivityAuditManager.addActivityAudit() is:

public static void addActivityAudit(String action, Merchant merchant, IMerchantUserAccount user) {
    ActivityAudit activityAudit = new ActivityAudit(merchant, action, user, new Date());
    activityAuditDAO.saveOrUpdate(activityAudit);
}

The exception I'm getting is:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing

but as far as I can tell I am.

ETA mapping:

<class name="com.rc.model.ActivityAudit" table="activity_audit" discriminator-value="0">
...
    <many-to-one name="merchant" class="com.rc.model.Merchant"
                 column="merchantid" unique="false" not-null="true" cascade="none"/>
...

I tried cascade="all" and cascade="save-update" and neither improves the situation.

ETA: See my own answer, below, but cascade="save-update" actually did fix it.


Solution

  • There were two problems. The second one, which was uncovered when I fixed the first, initially obscured the fact that cascade="save-update" actually did resolve this issue.

    In this question, object references an unsaved transient instance - save the transient instance before flushing user nanospeck posted a method for debugging that helped me a lot.

    I didn't notice the second problem until I used that debugging method and examined the Exception in more detail.