ISession.Lock does not determine proxies when proxies are used in a many to 
many relation using cascading.

Given is the following mapping:

<class name="Person" table="Persons" >
  <id name="Id">
    <generator class="hilo">
      <param name="table">AppDBHiLo</param>
      <param name="column">NextHiValue</param>
      <param name="max_lo">10</param>
    </generator>
  </id>

  <list name="Contacts" lazy="true" cascade="all-delete-orphan" 
table="Persons_Contacts">
    <key column="PersonId"/>
    <index column="Position"></index>
    <many-to-many class="Contact" column="ContactId"/>
  </list>
</class>

<class name="Contact" table="Contacts" >
  <id name="Id">
    <generator class="hilo">
      <param name="table">AppDBHiLo</param>
      <param name="column">NextHiValue</param>
      <param name="max_lo">10</param>
    </generator>
  </id>

  <list name="Entries" lazy="true" cascade="all-delete-orphan" 
table="Contacts_ContactEntries">
    <key column="ContactId"/>
    <index column="Position"></index>
    <many-to-many class="ContactEntry" column="ContactEntryId"/>
  </list> 
</class>

<class name="ContactEntry" table="ContactEntries" >
  <id name="Id">
    <generator class="hilo">
      <param name="table">AppDBHiLo</param>
      <param name="column">NextHiValue</param>
      <param name="max_lo">10</param>
    </generator>
  </id>
  <discriminator column="EntryType" insert="false" type="int"/> 
  <property name="EntryType" not-null="false" />

  <joined-subclass name=" ContactEntryPostalAddress" 
table="ContactEntryPostalAddresses">
    <key column="ContactEntryId"/>
    <property name="Street" not-null="false" />
    <property name="PostalCode" not-null="false" />
    <property name="City" not-null="false" />
    <property name="Country" not-null="false" /> 
  </joined-subclass>
    
  <joined-subclass name="ContactEntryValue" table="ContactEntryValues">
    <key column="ContactEntryId"/>
    <property name="Value" not-null="false" /> 
  </joined-subclass>
</class>

EntryType is an enum with values: PostalAddress = 0, Value = 1. Proxies are 
always generated for all entities using an interceptor.

   1. A person is loaded in a thread with its own session. The session is 
   disposed as soon as loading has finished.
   2. The person is locked to the session available inside the GUI-thread 
   using ISession.Lock(person, LockMode.None).
   3. A Contact is removed from the person’s contacts list and the session 
   is flushed.
   4. Cascading with “all-delete-orphan” deletes the unreferenced contact 
   and its associated contact entries.
   
This leads to a foreign key constraint violation because contact entries in 
the removed contact are only deleted in the base class table.
Tracking this down reveals that ISession.Lock does not evaluate proxies and 
therefor does not find the concrete subclass represented by that object. 
This happens in NHibernate.Persister.Entity.AbstractEntityPersister# 
GetSubclassEntityPersister(object instance, ISessionFactoryImplementor 
factory, EntityMode entityMode) 
(https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs#L4049).
 
This is commented in the source code:
// TODO : really need a way to do something like :
//     
 getTuplizer(entityMode).determineConcreteSubclassEntityName(instance)

The corresponding code in Hibernate has changed 
(https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java#L4381).

Is there an issue for that problem and can I expect a fix next time?

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"nhibernate-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to nhibernate-development+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to