I have a problem where an object is part of an IList<T> retrieved uasing the same session as it is updated and called on the ISession.Update() method, with a transaction around the Update().
In Nhibernate.Proxy.LazyInitializer at the Session property a value is being assigned and it differs from the previous ISessionImpl. The timestamp does not match the one used to retrieve the objects, nor another session I opened using the same factory. Does NHibernate create its own?
It appears to be related to he <many-to-one> mappings, the call stack indicates that the Plan class below is involved. But it is excluded from update in the mapping and the cascade has been set to just about all the options (all, none, save-update, no attribute specified) and it still tries to update the Plan.
It appears that the FK (Plan) objects are being read when package objects are being read. I thought this mapping would suppress this along with the
<property name="hibernate.max_fetch_depth">0</property>.
Perhaps the first step is to get the loading of the plans to stop.
The message in the exception is:
Illegally attempted to associate a proxy with two open Sessions
Thanks for the help, or even the appropriate RTFM redirect. I have, and I am not finding it.
Here are details requested:
Hibernate version: 1.2.0.1001 (Alpha May-28)
Mapping documents:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="PRG.CPFS.Objects.Package,PRG.CPFS.Objects" table="package" lazy="true" dynamic-update="true" dynamic-insert="true">
<id name="PackageIdentifier" column="[package]" type="Int32" unsaved-value="0">
<generator class="assigned"/>
</id>
<property column="[package_type]" type="String" name="PackageType" not-null="true" length="10" />
<property column="[plan]" type="String" name="Plan" not-null="true" length="6" />
.
. [more properties]
.
<property column="[scenario]" type="Boolean" name="Scenario" not-null="true" />
<property column="[automated]" type="Boolean" name="Automated" not-null="true" />
<many-to-one name="StatusObject" class="PRG.CPFS.Objects.PackageStatus, PRG.CPFS.Objects" update="false" insert="false" cascade="all">
<column name="[status]" />
</many-to-one>
<many-to-one name="PlanObject" class="PRG.CPFS.Objects.Plan, PRG.CPFS.Objects" update="false" insert="false" cascade="all">
<column name="[plan]" />
</many-to-one>
<many-to-one name="PeriodTypeObject" class="PRG.CPFS.Objects.PeriodType, PRG.CPFS.Objects" update="false" insert="false" cascade="all">
<column name="[period_type]" />
</many-to-one>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
It updates the Status property and then through a DAL abstraction calls Session.Update on the object.
Full stack trace of any exception that occurs:
at NHibernate.Proxy.LazyInitializer.set_Session(ISessionImplementor value) in c:\net\nhibernate\nhibernate\src\NHibernate\Proxy\LazyInitializer.cs:line 211
at NHibernate.Impl.SessionImpl.ReassociateProxy(LazyInitializer li, INHibernateProxy proxy) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1083
at NHibernate.Impl.SessionImpl.ReassociateIfUninitializedProxy(Object value) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1015
at NHibernate.Impl.ProxyVisitor.ProcessEntity(Object value, EntityType entityType) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\ProxyVisitor.cs:line 19
at NHibernate.Impl.AbstractVisitor.ProcessValue(Object value, IType type) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\AbstractVisitor.cs:line 61
at NHibernate.Impl.AbstractVisitor.ProcessValues(Object[] values, IType[] types) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\AbstractVisitor.cs:line 30
at NHibernate.Impl.AbstractVisitor.Process(Object obj, IEntityPersister persister) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\AbstractVisitor.cs:line 82
at NHibernate.Impl.SessionImpl.DoUpdateMutable(Object obj, Object id, IEntityPersister persister) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1649
at NHibernate.Impl.SessionImpl.DoUpdate(Object obj, Object id, IEntityPersister persister) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1664
at NHibernate.Impl.SessionImpl.Update(Object obj) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1505
at PRG.Common.NHibernate.DataAccessBase`1.Update(Object item, ISession session, ITransaction transaction) in C:\Documents and Settings\bsayles\My Documents\Visual Studio 2005\Projects\Client Reporting\PRG.Common.NHibernate\DataAccessBase.cs:line 225
Name and version of the database you are using:
MS SQL 2000 sp3
The generated SQL (show_sql=true):
SELECT this_.[package] as column1_0_, this_.[updated_by] as column15_53_0_, this_.[archived_date] as column9_53_0_, this_.[reviewer] as column19_53_0_, this_.[analyst] as column18_53_0_, this_.[removed] as column17_53_0_, this_.[created] as column12_53_0_, this_.[plan_year] as column11_53_0_, this_.[end_date] as column5_53_0_, this_.[period_type] as column6_53_0_, this_.[scenario] as column21_53_0_, this_.[expected_receipt_date] as column10_53_0_, this_.[updated] as column14_53_0_, this_.[created_by] as column13_53_0_, this_.[mailed_date] as column8_53_0_, this_.[period_num] as column7_53_0_, this_.[plan] as column3_53_0_, this_.[automated] as column22_53_0_, this_.[status] as column20_53_0_, this_.[begin_date] as column4_53_0_, this_.[package_type] as column2_53_0_, this_.[previous_package] as column16_53_0_ FROM package this_ WHERE this_.[status] = @p0 and this_.[removed] = @p1
This one appears okay.
SELECT plan0_.[plan] as column1_0_, plan0_.[automated] as column13_58_0_, plan0_.[active] as column10_58_0_, plan0_.[plan_type] as column8_58_0_, plan0_.[year_end] as column2_58_0_, plan0_.[suspended] as column11_58_0_, plan0_.[created] as column4_58_0_, plan0_.[created_by] as column5_58_0_, plan0_.[priority] as column3_58_0_, plan0_.[non_standard_plan_year_period] as column9_58_0_, plan0_.[updated_by] as column7_58_0_, plan0_.[fileset] as column12_58_0_, plan0_.[updated] as column6_58_0_ FROM [plan] plan0_ WHERE plan0_.[plan]=@p0
Why this is being done, I need to find out. with fetch set at 0 it should not, I thought.
Debug level Hibernate log excerpt:
The pertinent parts appear to be:
19:12:37,082 DEBUG [InitializeEntitiesAndCollections] {NHibernate.Loader.Loader.InitializeEntitiesAndCollections(c:\net\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:513)} total objects hydrated: 1950
19:12:37,082 DEBUG [InitializeEntity] {NHibernate.Impl.SessionImpl.InitializeEntity(c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:2834)} resolving associations for: [PRG.CPFS.Objects.Package#13000]
19:12:37,082 DEBUG [DoLoadByClass] {NHibernate.Impl.SessionImpl.DoLoadByClass(c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:2462)} loading [Plan#001022]
19:12:37,691 DEBUG [DoLoadByClass] {NHibernate.Impl.SessionImpl.DoLoadByClass(c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:2462)} loading [PackageStatus#AUTOSTART]
19:12:37,863 DEBUG [DoLoadByClass] {NHibernate.Impl.SessionImpl.DoLoadByClass(c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:2462)} loading [PeriodType#D]
This shows the many-to-one are non-lazy, and the IInterceptor.OnLoad in the source must be using a different session. But I need to stop this query altogether. To be continued:
|