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.  [ 5 posts ] 
Author Message
 Post subject: NHibernate 1.2.0 extends issue with multiple assemblies
PostPosted: Tue May 15, 2007 8:03 am 
Senior
Senior

Joined: Thu Feb 09, 2006 1:30 pm
Posts: 172
On a relatively large project (Currently over 400 mapped classes) we just tried to upgrade NHibernate from 1.0.3 to 1.2.0.GA. We hit a snag right in the beginning, where it will no longer allow us to have a class in one assembly which extends a class in another assembly. Note that we are using the one file per class and embedded resource pattern for all mapping files.

Due to certain reasons we are required to put certain classes in one assembly and other classes in another. Really it is to provide a framework that could be applied to other applications (even though it is yet to be used for such). Because of this we have core framework classes that functional modules of our application inherit from. With NHibernate 1.0.3 everything worked fine, we just gave the fully qualified class name of the class we inherited from. The references are all correct and the application assembly references the framework assembly.

With 1.2.0.GA I see an error stating "NHibernate.MappingException: These classes extend unmapped classes:" for all such classes. I looked through the source code of NHibernate 1.0.3 and NHibernate 1.2.0.GA and noticed that the OrderedHbmFiles(ISet) method was totally rewritten. I found that there was a bug with this code in the past and it needed to be resolved. I also noticed that the new method has a check at the bottom that if it extends classes and can not find those classes in the assembly it throws an exception. The old implementation would simply add them at the end since it wasn't sure where they needed to go.

As a workaround for now I changed the 1.2.0.GA source code locally to no longer perform that check in the end and to just add the given classes to the end of the sorted list of classes. After making this change everything appear to work for us.

So as a result would it be possible to consider this a bug and have the code changed in such a way where we could check to see if the necessary classes which are extended were already loaded? I was trying to see how to do this from the AssemblyHbmOrderer class but could not see an easy way to do it. If someone could point me in the right direction I would be willing to make the change.

Are there any other possible recommendations which could be made regarding this issue? I believe this should be considered a bug with 1.2.0.GA.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 15, 2007 8:21 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Yes, this is a bug that was reported and will be fixed in 1.2.1. The solution would probably be to let the orderer know about classes that were already loaded, for example by passing a reference to the session factory or Mappings to it.


Top
 Profile  
 
 Post subject: Hibernate joined-subclass problem
PostPosted: Fri May 25, 2007 5:56 am 
Beginner
Beginner

Joined: Fri May 25, 2007 5:55 am
Posts: 26
Hi,

I am stuck on this also. What is a valid workaround for this.

thanks,
Richie.


Top
 Profile  
 
 Post subject: Re: Hibernate joined-subclass problem
PostPosted: Fri May 25, 2007 7:44 am 
Senior
Senior

Joined: Thu Feb 09, 2006 1:30 pm
Posts: 172
rmswalsh wrote:
Hi,

I am stuck on this also. What is a valid workaround for this.

thanks,
Richie.


You can try using the overload for the AddAssembly method where you state that it should not use the orderer. That will cause NHibernate to skip this section of the code. I did not think that would work for me, so I changed the NHibernate source code and rebuilt it. I changed the code in the AssemblyHbmOrderer:OrderedHbmFiles(ISet) method to:

Code:
// Make sure joined-subclass mappings are loaded after base class
         ArrayList sortedList = new ArrayList();
         ISet processedClassNames = new HashedSet();
         ArrayList processedInThisIteration = new ArrayList();

         while (true)
         {
            foreach (ClassEntry ce in unorderedClasses)
            {
               if (ce.FullExtends == null || processedClassNames.Contains(ce.FullExtends))
               {
                  // This class extends nothing, or is derived from one of the classes that were already processed.
                  // Append it to the list since it's safe to process now.
                  sortedList.Add(ce);
                  processedClassNames.Add(ce.FullClassName);
                  processedInThisIteration.Add(ce);
               }
            }

            unorderedClasses.RemoveAll(processedInThisIteration);

            if (processedInThisIteration.Count == 0)
            {
               if (!unorderedClasses.IsEmpty)
               {
                  //throw new MappingException(FormatExceptionMessage(unorderedClasses));
                       
                        //If we couldn't find a matching base class we'll just load them last.
                        //hopefully the class was loaded with a prior assembly.
                        sortedList.AddRange(unorderedClasses);
               }
               break;
            }

            processedInThisIteration.Clear();
         }

         // now that we know the order the classes should be loaded - order the
         // hbm.xml files those classes are contained in.
         StringCollection loadedFiles = new StringCollection();
         foreach (ClassEntry ce in sortedList)
         {
            // Check if this file already loaded (this can happen if
            // we have mappings for multiple classes in one file).
            if (loadedFiles.Contains(ce.FileName) == false)
            {
               loadedFiles.Add(ce.FileName);
            }
         }

         return loadedFiles;


Note the key section where I commented out the throw new MappingException. Instead of saying I couldn't find a class to extend I just assume I could and load those files last.

This is actually what NHibernate 1.0.x used to do, and why I decided it was safe to do it. Now if these classes really don't exist there will be problems, but we can verify that on our own for now.

We plan to use this build until 1.2.1 comes out, at which time we'll replace our build with the standard release.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 05, 2007 4:14 am 
Beginner
Beginner

Joined: Fri May 25, 2007 5:55 am
Posts: 26
Thanks for that. I cant seem to give you a credit for this as I didnt start the thread so sorry about that.

I got around this by adding the HBM files to the Assembly and to set them to copy is newer so that they appear in the bin folder.

thanks,
Richie.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.