These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Cascades do not reach entity collection keys
PostPosted: Wed Sep 03, 2008 1:23 am 
Newbie

Joined: Mon Nov 19, 2007 12:12 am
Posts: 5
I think this is a bug. Basically if I use index-many-to-many or index-many-to-any to map an entity key of a dictionary this key is not reassociated with a new session through an update() even though I specify cascade = save-update on the collection. This then becomes a problem when the same object is retrieved in the new session because a lazy reference to it is resolved. It isn't in the PersistenceContext (because the cascade never occured on load of the dictionary) so a new instance is created. Should I report this to Jira?


Hibernate version: Local Build from nhibernate\src\NHibernate source at revision 3589. Update I have also just replicated this using 2.0.0GA. Same thing happens


Mapping documents:

Code:
  <class name="Project" table="Project" lazy="false">
    <id name="Name" type="String">
      <column name="Name"/>
      <generator class="assigned" />
    </id>
     <map name="nodeValue" table="NodeValue" access="field" cascade="save-update" lazy="false">
        <key column="id"/>
        <index-many-to-many column="Node" class="Node"/>
      <element column="aNodeValue" type="double"/>
     </map>
    <many-to-one name="aScenario" column="Scenario" access="field" cascade="all"/>   
  </class>
  <class name="Scenario" table="Scenario" lazy="true">
    <id type="Int32" name="id">
      <column name="ScenarioID"/>
      <generator class="increment" />
    </id>
    <property name="Name">
      <column name="Name"/>
    </property>
    <list name="Nodes" cascade="all">
      <key column="NodeListID"/>
      <index column ="NodeListIndex"/>
      <one-to-many class="Node"/>
    </list>   
  </class>
  <class name="NHibernateSandbox.Node" table="Node" lazy="false">
    <id type="Int32"  name="id">
      <column name="NodeIdentifier"/>
      <generator class="increment" />
    </id>
    <property name="Name">
      <column name="Name"/>
    </property>
  </class>



Code between sessionFactory.openSession() and session.close():
Code:
            //Open a session and transaction
            ISession session = sf.OpenSession( cnn );
            ITransaction tx = session.BeginTransaction( );

            //Load the project
            //The scenario is lazy loaded
            //nodeA is loaded as part of the project dictionary nodeValue
            project = session.Get<Project>( "Test" );
           
            //Commit the transaction and cloase the session
            tx.Commit( );
            session.Close( );


            //Open a new session and transaction
            session = sf.OpenSession( cnn );
            tx = session.BeginTransaction( );

            //Cascade (as specified in xml mapping files) through the detached object
            //reassociate objects and save any changes back to the database
            session.Update( project );

           
            //Get the key out of the dictionary
            IEnumerator enumer;           
            enumer = project.nodeValue.Keys.GetEnumerator( );
            enumer.MoveNext( );

            //Compare the key which is nodeA to the first item in the scenario Nodes list
            //This list is lazy load and loads when this comparison takes place.
            //Even though the id's of nodeA are the same the object instances are different
            //This appears to be because nodeA was not added to the PersistentContext during update
            //If nodeA is stored in project as a property or in a list it is correctly added to
            //the dictionary. This error only occurs when nodeA is a key in a dictionary mapped
            //with index-many-to-many or index-many-to-any
            if( enumer.Current != project.aScenario.Nodes[0] )
                MessageBox.Show( "Key Node and scenario Node should be the same instance" );
            tx.Commit( );
            session.Close( );


Name and version of the database you are using: Firebird 2.1.0

The generated SQL:
Code:
create table Scenario (ScenarioID INTEGER not null, Name VARCHAR(255), primary key (ScenarioID))
create table Project (Name VARCHAR(255) not null, Scenario INTEGER, primary key (Name))
create table NodeValue (id VARCHAR(255) not null, aNodeValue DOUBLE PRECISION, Node INTEGER not null, primary key (id, Node))
create table Node (NodeIdentifier INTEGER not null, Name VARCHAR(255), NodeListID INTEGER, NodeListIndex INTEGER, primary key (NodeIdentifier))
alter table Project add constraint FKCFC6D85A757B75B4 foreign key (Scenario) references Scenario
alter table NodeValue add constraint FK3085E2DC77DA1F6B foreign key (id) references Project
alter table NodeValue add constraint FK3085E2DC7F85E57B foreign key (Node) references Node
alter table Node add constraint FK76534CD8F176736F foreign key (NodeListID) references Scenario
NHibernate: INSERT INTO Scenario (Name, ScenarioID) VALUES (@p0, @p1); @p0 = '', @p1 = '1'
NHibernate: INSERT INTO Node (Name, NodeIdentifier) VALUES (@p0, @p1); @p0 = '', @p1 = '1'
NHibernate: INSERT INTO Project (Scenario, Name) VALUES (@p0, @p1); @p0 = '1', @p1 = 'Test'
NHibernate: UPDATE Node SET NodeListID = @p0, NodeListIndex = @p1 WHERE NodeIdentifier = @p2; @p0 = '1', @p1 = '0', @p2 = '1'
NHibernate: INSERT INTO NodeValue (id, Node, aNodeValue) VALUES (@p0, @p1, @p2); @p0 = 'Test', @p1 = '1', @p2 = '1'
NHibernate: SELECT project0_.Name as Name1_0_, project0_.Scenario as Scenario1_0_ FROM Project project0_ WHERE project0_.Name=@p0; @p0 = 'Test'
NHibernate: SELECT nodevalue0_.id as id0_, nodevalue0_.aNodeValue as aNodeValue0_, nodevalue0_.Node as Node0_ FROM NodeValue nodevalue0_ WHERE nodevalue0_.id=@p0; @p0 = 'Test'
NHibernate: SELECT node0_.NodeIdentifier as NodeIden1_3_0_, node0_.Name as Name3_0_ FROM Node node0_ WHERE node0_.NodeIdentifier=@p0; @p0 = '1'
NHibernate: SELECT scenario0_.ScenarioID as ScenarioID0_0_, scenario0_.Name as Name0_0_ FROM Scenario scenario0_ WHERE scenario0_.ScenarioID=@p0; @p0 = '1'
NHibernate: SELECT nodes0_.NodeListID as NodeListID1_, nodes0_.NodeIdentifier as NodeIden1_1_, nodes0_.NodeListIndex as NodeList4_1_, nodes0_.NodeIdentifier as NodeIden1_3_0_, nodes0_.Name as Name3_0_ FROM Node nodes0_ WHERE nodes0_.NodeListID=@p0; @p0 = '1'
NHibernate: UPDATE Project SET Scenario = @p0 WHERE Name = @p1; @p0 = '1', @p1 = 'Test'


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.