I have an application that uses Hibernate mapping xml files to define the metadata of our entities. I handle the persistence of related entities with join tables, referencing foreign keys of the associated entities. Most of the related entities are mapped using inverse, lazy, noop, one-to-many bag definitions. With some of the latest Hibernate core Java releases, I have started running into issues with our entity's transient collections.
Example mappings: <class name="Invoice" table="Invoice"> <cache usage="read-write" /> <id name="id" column="InvoiceID" type="int"> <generator class="identity" /> </id> <many-to-one lazy="false" name="invoiceType" column="InvoiceTypeID" class="InvoiceType" /> <many-to-one lazy="false" name="businessClient" column="ClientID" class="Client" /> <property name="invoiceDate" column="InvoiceDate" type="date" /> <property name="totalAmount" column="TotalAmount" type="big_decimal" precision="19" scale="2" /> <property name="paidAmount" column="PaidAmount" type="big_decimal" precision="19" scale="2" /> <property name="voidReason" column="VoidReason" /> <property name="documentFileCount" column="DocumentFileCount" /> <property name="createUserId" column="CreateUserID" update="false" /> <property name="createDate" column="CreateDate" update="false" /> <property name="updateUserId" column="UpdateUserID" /> <property name="updateDate" column="UpdateDate" /> <property name="rv" column="rv" insert="false" update="false" /> <bag lazy="true" name="detailList" access="noop" inverse="true"> <key column="InvoiceID" /> <one-to-many class="InvoiceDetail" /> </bag> </class>
<class name="InvoiceDetail" table="InvoiceDetail"> <cache usage="read-write" /> <id name="id" column="InvoiceDetailID" type="int"> <generator class="identity" /> </id> <many-to-one lazy="false" name="invoice" column="InvoiceID" class="Invoice" /> <property name="billingAmount" column="BillingAmount" type="big_decimal" precision="19" scale="2" /> <property name="note" column="InvoiceDetailNote" /> <property name="createUserId" column="CreateUserID" update="false" /> <property name="createDate" column="CreateDate" update="false" /> <property name="updateUserId" column="UpdateUserID" /> <property name="updateDate" column="UpdateDate" /> <property name="rv" column="rv" insert="false" update="false" /> </class>
I have started to encounter issues with dirty checking and reassociation of detached collections for these bag references. Both issues started with Hibernate 4.3.11 and 5.0.3 and later (did not test Hibernate 5 releases prior to 5.0.3). - Dirty checking - have created a ticket for this (https://hibernate.atlassian.net/browse/HHH-10404) because for versioned entities, the entity gets updated due to these lazy, noop bags being identified as dirty. The updates to the versioned entity only updates the version column, which causes issues because it unnecessarily accesses the DB and establishes a lock on the table causing intermittent deadlocks for some long running transactions. - Reassociation of bag failures - upon deleting entities we do a lookup within transaction to clean up/validate related associations. The original entity is detached because it was loaded in a previous transaction. The lazy, noop collection is causing the exception with message "could not reassociate uninitialized transient collection."
If I am understanding the noop access method and non-cascading, lazy bag definition, shouldn't these collections be treated as transient and excluded from all dirty checking and reassociation?
I have done some digging and it appears that both of the above issues started after applying https://hibernate.atlassian.net/browse/HHH-9777. Was an edge case missed with this ticket?
|