Hi,
I have a problem when running a test case against Oracle. Against MS SQL everything works fine.
We're using
NHibernate 2.0. The problem occures when saving a standard Client/Department/User hierachy
This is the mapping document:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="field" assembly="MammutSoft.Data.DomainModel" namespace="ch.MammutSoft.Data.DomainModel.Implementation">
<class name="OrgUnit" table="V_ORGUNIT">
<id name="_id" column="ORGUNIT_ID">
<generator class="native">
<param name="sequence">SQ_ORGUNIT</param>
</generator>
</id>
<discriminator column="ORGUNIT_TYPE" type="string" />
<version name="_version" />
<property name="_names" type="ch.MammutSoft.Core.MscStringCollectionUserType, MammutSoft.Core" column="NAMES" />
<property name="_postalAddressDiffersFromParent" column="POSTADR_DIFFERS_FROM_PARENT" />
<!--
!!! access="property", if a childs address is the same as the parents address, the references must be same. This is handled
by the Property and thus here we use the property
-->
<many-to-one name="PostalAddress" access="property" class="PostalAddress" column="POSTAL_ADDRESS_ID" cascade="all" fetch="join" />
<many-to-one name="_parent" column="PARENT_ORGUNIT_ID" class="OrgUnit" not-null="false" insert="false" update="false" />
<bag name="_children" fetch="join" cascade="all" >
<key column="PARENT_ORGUNIT_ID" />
<one-to-many class="OrgUnit" not-found="ignore"/>
</bag>
<subclass name="Client" discriminator-value="Client">
<component name="_defaultCurrency" class="Currency">
<property name="DBSimpleValue" column="DEFAULT_CURRENCY_ISO_CODE" access="property" />
</component>
<bag name="_debitAccounts" cascade="all" >
<key column="CLIENT_ID" />
<one-to-many class="DebitAccount" not-found="ignore"/>
</bag>
</subclass>
<subclass name="Department" discriminator-value="Department" />
<subclass name="User" discriminator-value="User">
<many-to-one name="_primaryLogin" class="PrimaryLogin" column="PRIMARY_LOGIN_ID" cascade="all" fetch="join" />
<!--<bag name="_roles" access="field" fetch="join" >
<key column="PARENT_ORGUNIT_ID" />
<one-to-many class="OrgUnit" not-found="ignore"/>
</bag>-->
</subclass>
</class>
</hibernate-mapping>
In the test case I create a hierachy programatically and then save it with one single call to SaveOrUpdate() on each client, which is the top most hierachy item.
This is the sql log from NHibernate :
Code:
NHibernate: SELECT this_.COUNTRY_ISO_CODE as COUNTRY1_31_0_, this_.INTERNAL_NAME as INTERNAL2_31_0_ FROM DIC_COUNTRY this_
NHibernate: SELECT this_.CURRENCY_ISO_CODE as CURRENCY1_20_0_, this_.CONVERSION_FACTOR as CONVERSION2_20_0_, this_.INTERNAL_NAME as INTERNAL3_20_0_ FROM DIC_CURRENCY this_
NHibernate: select SQ_ORGUNIT.nextval from dual
NHibernate: select SQ_POSTAL_ADDRESS.nextval from dual
NHibernate: select SQ_ORGUNIT.nextval from dual
NHibernate: select SQ_ORGUNIT.nextval from dual
NHibernate: select SQ_PRIMARY_LOGIN.nextval from dual
NHibernate: select SQ_SECONDARY_LOGIN.nextval from dual
NHibernate: INSERT INTO V_POSTAL_ADDRESS (VERSION, STREET, POBOX, ZIP_CODE, TOWN, COUNTRY_ISO_CODE, POSTAL_ADDRESS_ID) VALUES (:p0, :p1, :p2, :p3, :p4, :p5, :p6); :p0 = '1', :p1 = 'Lerchenweg 13', :p2 = '', :p3 = '5036', :p4 = 'Oberentfelden', :p5 = 'CH', :p6 = '1'
NHibernate: INSERT INTO V_ORGUNIT (VERSION, NAMES, POSTADR_DIFFERS_FROM_PARENT, POSTAL_ADDRESS_ID, DEFAULT_CURRENCY_ISO_CODE, ORGUNIT_TYPE, ORGUNIT_ID) VALUES (:p0, :p1, :p2, :p3, :p4, 'Client', :p5); :p0 = '1', :p1 = '<ArrayOfString>
<string>mammut-soft computing ag</string>
<string>Business Banking Software</string>
</ArrayOfString>', :p2 = 'False', :p3 = '1', :p4 = 'CHF', :p5 = '1'
NHibernate: INSERT INTO V_ORGUNIT (VERSION, NAMES, POSTADR_DIFFERS_FROM_PARENT, POSTAL_ADDRESS_ID, ORGUNIT_TYPE, ORGUNIT_ID) VALUES (:p0, :p1, :p2, :p3, 'Department', :p4); :p0 = '1', :p1 = '<ArrayOfString>
<string>Product Management</string>
</ArrayOfString>', :p2 = 'False', :p3 = '1', :p4 = '2'
NHibernate: INSERT INTO V_SECONDARY_LOGIN (VERSION, BANK, APPLICATION, LOGIN_MODE, RECORD_HASH, SECONDARY_LOGIN_ID) VALUES (:p0, :p1, :p2, :p3, :p4, :p5); :p0 = '1', :p1 = '', :p2 = '', :p3 = '0', :p4 = '0', :p5 = '1'
NHibernate: INSERT INTO V_PRIMARY_LOGIN (VERSION, PRINCIPAL, CREDENTIALS, IS_LOCKED, EXPIRATION_DATE, CREDENTIALS_CHANGED_DATE, LOGIN_FAILURE_COUNT, LOGIN_SUCCESS_COUNT, CURRENT_LOGIN_FAILURE_COUNT, RECORD_HASH, SECONDARY_LOGIN_ID, PRIMARY_LOGIN_ID) VALUES (:p0, :p1, :p2, :p3, :p4, :p5, :p6, :p7, :p8, :p9, :p10, :p11); :p0 = '1', :p1 = 'skl', :p2 = 'skl', :p3 = 'False', :p4 = '', :p5 = '', :p6 = '0', :p7 = '0', :p8 = '0', :p9 = '0', :p10 = '1', :p11 = '1'
NHibernate: INSERT INTO V_ORGUNIT (VERSION, NAMES, POSTADR_DIFFERS_FROM_PARENT, POSTAL_ADDRESS_ID, PRIMARY_LOGIN_ID, ORGUNIT_TYPE, ORGUNIT_ID) VALUES (:p0, :p1, :p2, :p3, :p4, 'User', :p5); :p0 = '1', :p1 = '<ArrayOfString>
<string>Stefanie Kälin-Lederer</string>
</ArrayOfString>', :p2 = 'False', :p3 = '1', :p4 = '1', :p5 = '3'
NHibernate: UPDATE V_ORGUNIT SET VERSION = :p0, NAMES = :p1, POSTADR_DIFFERS_FROM_PARENT = :p2, POSTAL_ADDRESS_ID = :p3 WHERE ORGUNIT_ID = :p4 AND VERSION = :p5; :p0 = '2', :p1 = '<ArrayOfString>
<string>Product Management</string>
</ArrayOfString>', :p2 = 'True', :p3 = '1', :p4 = '2', :p5 = '1'
The last Update produces an HibernateOptimisticLockingFailureException. I've checked the id and the version of the record and both are correct. So the update should update exactly one record.
As I said the same test case against MS SQL Server 2005 works fine.
I'm fighting with this problem the whole day, any help is appreciated.
Thanks in advance
Andreas