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.  [ 10 posts ] 
Author Message
 Post subject: one-to-many many-to-one urgent problem
PostPosted: Thu Oct 12, 2006 10:39 am 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
Hello forum.

I have this mmaping file:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
   <class name="PersistentClasses.Role, PersistentClasses" table="ROLS">
      <id name="Rol" column="ROL" type="Byte">
         <generator class="assigned" />
      </id>
      <property name="Descripcio" column="DESCRIPCIO" type="String" length="16"/>
      <set name="Users" inverse="true" cascade="all">
         <key column="ROL"/>
         <one-to-many class="PersistentClasses.User, PersistentClasses"/>
      </set>
   </class>
</hibernate-mapping>


So, when I perform

Code:
rol = (PersistentClasses.Role)this.session.Load(typeof(PersistentClasses.Role),key);


NHibernate doesn't load all users of each role.

I would like me that NHibernate loads automatically all users that belongs to each role. I thank that with
Quote:
cascade="all"


or with

Quote:
lazy="true"


was enought.

What Must I add to role.hbm.xml mapping file?


Last edited by jeusdi on Fri Oct 13, 2006 5:14 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 13, 2006 5:13 am 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
Please, I'm wonder because I can't solve it.

I type you role.hbm.xml, user.hbm.xml, user.cs, role.cs, UserFactory.cs and RoleFactory.cs.

I think that when I perform

Code:
rol = (PersistentClasses.Role)this.session.Load(typeof(PersistentClasses.Role),key);


NHibernate should obtain or initialize Users property as a collection of Users, but it isn't how I think. After I've performed Load function I try to access to Users property of rol, but how Users is null, .NET throws an Exception.

When I load an User, your Role property is initialitzed correctly, but Users property of Role isn't initialized!!!

Thanks in advance

Main thread -->
Code:
PersistentClasses.RolFactory roleFactory = new PersistentClasses.RolFactory();
         PersistentClasses.Role rol = new PersistentClasses.Role(60,"NHibernate");
         roleFactory.saveRol(rol);
         PersistentClasses.Role rol2 = new PersistentClasses.Role(61,"NHibernate2");
         roleFactory.saveRol(rol2);
         PersistentClasses.UserFactory userFactory = new PersistentClasses.UserFactory();
         PersistentClasses.User usuari = new PersistentClasses.User("Jordi","password","Jordi",rol);
         userFactory.saveUser(usuari);

         usuari.Rol = rol2;
         userFactory.updateUser(usuari);

         PersistentClasses.User useri = userFactory.getUser("Jordi");
         PersistentClasses.Role role = roleFactory.getRole(61);

-----------------All is Ok to here, but when I access to role.Users crashes because it's null--------------------

         foreach (PersistentClasses.User user in role.Users)
         {
            this.listBoxControl1.Items.Add(user.Name);
         }


Role.cs
Code:
   public class Role
   {

      private byte rol;
      private string descripcio;
      private System.Collections.IDictionary users;

      public Role()
      {
         this.rol = 0;
         this.descripcio = "";
         this.users = null;
      }

      public Role(byte rol, string descripcio)
      {
         this.rol = rol;
         this.descripcio = descripcio;
      }

      public string Descripcio
      {
         get { return this.descripcio; }
         set { this.descripcio = value; }
      }

      public byte Rol
      {
         get { return this.rol; }
         set { this.rol = value; }
      }

      public System.Collections.IDictionary Users
      {
         get { return this.users; }
         set { this.users = value; }
      }
   }


User.cs-->
Code:
public class User
   {
      
      private string login;
      private string password;
      private string name;
      private PersistentClasses.Role rol;

      public User()
      {
         this.login = "";
         this.password = "";
         this.name = "";
         this.rol = null;
      }

      public User(string login, string password, string nom, PersistentClasses.Role rol)
      {
         this.login = login;
         this.password = password;
         this.name = nom;
         this.rol = rol;
      }

      public string Login
      {
         get { return this.login; }
         set { this.login = value; }
      }

      public PersistentClasses.Role Rol
      {
         get { return this.rol; }
         set { this.rol = value; }
      }

      public string Name
      {
         get { return this.name; }
         set { this.name = value; }
      }

      public string Password
      {
         get { return this.password; }
         set { this.password = value; }
      }
   }


Role.hbm.xml
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
   <class name="PersistentClasses.Role, PersistentClasses" table="ROLS">
      <id name="Rol" column="ROL" type="Byte">
         <generator class="assigned" />
      </id>
      <property name="Descripcio" column="DESCRIPCIO" type="String" length="16"/>
      <set name="Users" inverse="true" lazy="true" table="USUARIS">
         <key column="ROL"/>
         <one-to-many class="PersistentClasses.User, PersistentClasses"/>
      </set>
   </class>
</hibernate-mapping>


User.hbm.xml-->
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
   <class name="PersistentClasses.User, PersistentClasses" table="USUARIS">
      <id name="Login" column="LOGIN" type="String" length="8">
         <generator class="assigned" />
      </id>
      <property name="Password" column="PASSWORD" type="String" length="16"/>
        <property name="Name" column="NOM" type="String" length="32"/>
        <many-to-one name="Rol" column="ROL" unique="true" not-null="true" class="PersistentClasses.Role,PersistentClasses"/>
        <!--<property name="Rol" column="ROL" type="Int16"/> -->
   </class>
</hibernate-mapping>


RoleFactory.cs-->
Code:
private NHibernate.Cfg.Configuration configuration;
      private NHibernate.ISessionFactory sessionFactory;
      private NHibernate.ISession session;

      public RolFactory()
      {
         this.configuration = new NHibernate.Cfg.Configuration();
         System.Collections.IDictionary props = new System.Collections.Hashtable();

         props["hibernate.connection.provider"] = "NHibernate.Connection.DriverConnectionProvider";
         props["hibernate.dialect" ] = "NHibernate.Dialect.MsSql2000Dialect";
         props["hibernate.connection.driver_class" ] = "NHibernate.Driver.SqlClientDriver" ;
         props["hibernate.connection.connection_string"] = "Server=PORTATIL;initial catalog=NHibernate;User ID=CABRE;Password=CABRE";

         foreach( System.Collections.DictionaryEntry de in props )
         {
            this.configuration.SetProperty( de.Key.ToString(), de.Value.ToString() );
         }

         this.configuration.AddAssembly("PersistentClasses");
         this.configuration.AddClass(typeof(PersistentClasses.Role));
         this.sessionFactory = this.configuration.BuildSessionFactory();
         this.session = this.sessionFactory.OpenSession();
      }

      public void saveRol(PersistentClasses.Role rol)
      {
         try
         {
            NHibernate.ITransaction transaction = this.session.BeginTransaction();

            this.session.Save(rol);

            transaction.Commit();
            this.session.Flush();
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.InnerException.Message);            
         }
      }

      public PersistentClasses.Role getRole(byte key)
      {
         NHibernate.ITransaction transaction = this.session.BeginTransaction();

         PersistentClasses.Role rol = new PersistentClasses.Role();
         try
         {
            rol = (PersistentClasses.Role)this.session.Load(typeof(PersistentClasses.Role),key);
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.InnerException.Message);
         }

         transaction.Commit();
         return rol;
      }


UserFactory.cs-->
Code:
   public class UserFactory
   {
      
      private NHibernate.Cfg.Configuration configuration;
      private NHibernate.ISessionFactory sessionFactory;
      private NHibernate.ISession session;

      public UserFactory()
      {
         this.configuration = new NHibernate.Cfg.Configuration();
         System.Collections.IDictionary props = new System.Collections.Hashtable();

         props["hibernate.connection.provider"] = "NHibernate.Connection.DriverConnectionProvider";
         props["hibernate.dialect" ] = "NHibernate.Dialect.MsSql2000Dialect";
         props["hibernate.connection.driver_class" ] = "NHibernate.Driver.SqlClientDriver" ;
         props["hibernate.connection.connection_string"] = "Server=PORTATIL;initial catalog=NHibernate;User ID=CABRE;Password=CABRE" ;

         foreach( System.Collections.DictionaryEntry de in props )
         {
            this.configuration.SetProperty( de.Key.ToString(), de.Value.ToString() );
         }

         this.configuration.AddAssembly("PersistentClasses");
         this.configuration.AddClass(typeof(PersistentClasses.User));
         this.configuration.AddClass(typeof(PersistentClasses.Role));
         this.sessionFactory = this.configuration.BuildSessionFactory();
         this.session = this.sessionFactory.OpenSession();
      }

      public void Dispose()
      {
         this.session.Dispose();
         this.sessionFactory.Close();
      }

      public void saveUser(PersistentClasses.User user)
      {
         try
         {
            NHibernate.ITransaction transaction = this.session.BeginTransaction();

            this.session.Save(user);

            transaction.Commit();
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.InnerException.Message);
         }
      }

      public PersistentClasses.User getUser(string login)
      {
         PersistentClasses.User user = new User();
         //user.Login = login;

         try
         {
            NHibernate.ITransaction transaction = this.session.BeginTransaction();

            user = (PersistentClasses.User)this.session.Get(typeof(PersistentClasses.User),login);

            transaction.Commit();
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.InnerException.Message);
         }
         return user;
      }

      public void updateUser(PersistentClasses.User user)
      {
         try
         {
            NHibernate.ITransaction transaction = this.session.BeginTransaction();

            this.session.Update(user);

            transaction.Commit();
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.InnerException.Message);
         }
      }
   }


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 13, 2006 6:32 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
If You use <set> mapping, property type must be either ISet or ICollection (or generic vwersion of them)

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 13, 2006 10:39 am 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
gert wrote:
If You use <set> mapping, property type must be either ISet or ICollection (or generic vwersion of them)

Gert


I've tested it with your changes, but It does't work neither.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 13, 2006 10:48 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
jeusdi wrote:
gert wrote:
If You use <set> mapping, property type must be either ISet or ICollection (or generic vwersion of them)

Gert


I've tested it with your changes, but It does't work neither.


As You do not clode session in between save and Get, the instance that was saved remains in cache. This in turn means that if You are not creating Set instance, the peorpety remain null.

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 13, 2006 2:52 pm 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
Mmm, So I don't understand why Role User property is initialized when I execute

Code:
user = (PersistentClasses.User)this.session.Get(typeof(PersistentClasses.User),login);


So, when this sentence is performed I can access to Role property of my user object, initilized correctly. In other words, NHibernate loads Role information of my user. However, I don't close the session, and this role should be in cache, and as you say, this property should not be loaded or initialized, this property should be null, no?

And other question, you say that
Quote:
This in turn means that if You are not creating Set instance, the property remain null.


Why? I don't understand you?

What Must I do to obtain my users collection?

Excese for my questions. Thanks for all.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 13, 2006 3:34 pm 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
Mmm, I've modified my RoleFactory in order to close the session after all save, update and get operations of role entity and I work correctly, In other words, when I want obtain an Role NHibernate loads User collection also. But I don't understand why when I close de session NHibernate loads all users of one role and if one user is in cache is not loaded in user collection of each role.

Can you explain it me, please?

RoleFactory.cs -->
Code:
...
public void saveUser(PersistentClasses.User user)
      {
         try
         {
            this.session = this.sessionFactory.OpenSession();
            NHibernate.ITransaction transaction = this.session.BeginTransaction();

            this.session.Save(user);

            transaction.Commit();
            this.session.Close();
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.InnerException.Message);
         }
      }

      public PersistentClasses.User getUser(string login)
      {
         PersistentClasses.User user = new User();
         //user.Login = login;

         try
         {
            this.session = this.sessionFactory.OpenSession();
            NHibernate.ITransaction transaction = this.session.BeginTransaction();

            user = (PersistentClasses.User)this.session.Get(typeof(PersistentClasses.User),login);

            transaction.Commit();
            this.session.Close();
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.InnerException.Message);
         }
         return user;
      }

      public void updateUser(PersistentClasses.User user)
      {
         try
         {
            this.session = this.sessionFactory.OpenSession();
            NHibernate.ITransaction transaction = this.session.BeginTransaction();

            this.session.Update(user);

            transaction.Commit();
            this.session.Close();
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.InnerException.Message);
         }
      }
   }
...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 13, 2006 4:21 pm 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
jeusdi wrote:
Mmm, So I don't understand why Role User property is initialized when I execute

Code:
user = (PersistentClasses.User)this.session.Get(typeof(PersistentClasses.User),login);


So, when this sentence is performed I can access to Role property of my user object, initilized correctly. In other words, NHibernate loads Role information of my user. However, I don't close the session, and this role should be in cache, and as you say, this property should not be loaded or initialized, this property should be null, no?

And other question, you say that
Quote:
This in turn means that if You are not creating Set instance, the property remain null.


Why? I don't understand you?

What Must I do to obtain my users collection?


One important thing: ISession contains first-level cache of objects. If a instance is requested from session, first the cache is searched for instance. If instance is found from cache, the database is never accessed.

So, save stores the instance in cache, and next time You request for the object, the otiginal instance Save() -d is returned.

Rest of should be deductable from that behaviour.

To force object to be re-read from database, You might try to use session.Evict(obj) or session.Frefresh(obj).

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 14, 2006 8:23 am 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
One more question. Each Session is the same that one connection? Each time that I open a session I'm openning a connection?

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 15, 2006 3:31 pm 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
jeusdi wrote:
One more question. Each Session is the same that one connection? Each time that I open a session I'm openning a connection?


Basically, yes. Of course, You can discoonect the session (so that connection is closed).

Gert

_________________
If a reply helps You, rate it!


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

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.