There are two ways to develop software: the wrong way and the fun way.
Tuesday, February 28, 2006
NHibernate debug
When you failed to maintain your relationship between entities correctly, and there is a cascade saveupdate, you will probably see this error.
<class husbande>
<one-to-one class=wife cascading=save-update>
….
Husband tom = new Husband();
Wife jane = new Wife();
tom.wife = jane;
sess.SaveOrUpdate(tom)
since you missed the jane.husband = tom;
you will get that err.
Aspnet 20 debug
If you saw a runtime error keep asking you to turn the customErrorPage mode=off, no matter it already set as off, it probably means that your web.config is corrupt.
Friday, February 24, 2006
ASP.NET 2.0 Building model
Tuesday, February 21, 2006
Running Asp.net 2.0 and 1.1 on IIS 6.0
Configuration tip: running ASP.NET 2.0 apps on IIS 6.0
This is something I came across this morning when deploying an ASP.NET 2.0 application. I installed .net framework beta 2 on to the box. I then configured the site through IIS to use .NET 2.0 version of the framework. (For those who aren't aware of this, .NET 2.0 inserts a new tab into your web site properties in IIS. This tab which is called "ASP.NET" enables you to set the version of the framework under which your application will run. It also has a few other cool features such as editing your web.config file through the UI).
Anyhow deployed the app and an hour later I got this error saying: ASP.NET Application Service is unavailable. First thing was check the event log on the IIS box which had a really informative error message:
It is not possible to run two different versions of ASP.NET in the same IIS process. Please use the IIS Administration Tool to reconfigure your server to run the application in a separate process. Please use the IIS Administration Tool to reconfigure your server to run the application in a separate process.
The solution from TechNet site was to create a seperate application pool for .NET 2.0 applications. My existing v1.1 apps continue to run in the defaultAppPool while my .NET 2.0 app now uses my AspNet2AppPool. The steps involved were:
A. To create a new Application Pool in IIS 6.0
Open the IIS management console and expand the local computer by clicking the plus sign.
Right-click the Application Pools folder, point to New, and then click Application Pool. The Add New Application Pool dialog box appears.
Enter the new pool name in the Application pool text box, and then click OK.
B. To assign my ASP.NET application to the new Application Pool
Open the IIS management console, expand the local computer by clicking the plus sign, and navigate to the folder that contains the ASP.NET application.
Right-click the application and then click Properties. The application's properties dialog box appears.
On the Directory tab, select the desired pool designation from the Application Pool list.
Further information available at: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconconfiguringaspnetapplicationforaspnetversion.asp
posted on Thursday, October 27, 2005 9:22 AM by jbrennan
Wednesday, February 15, 2006
NHibernate debugging
Exception Details: NHibernate.HibernateException: Cannot instantiate abstract class or interface: XXX.XXX.ISomeInterface
It's probably caused by the broken of the data integrity of the database, somebody has modified your database manually.
Saturday, February 04, 2006
Generic Sets and Collection Wrapper
Introduction
This simple library is developed for working with NHibernate 1.1 or lower. If there is no benefit of having a generic Set<T> that also implements Iesi.Collections.ISet from NHibnernate, you might be more interested in the C5 collection library or the PowerCollection.
This is a simple extension to JasonSmith's Iesi.Collections to offer a generic version of the ISet and its implementations. Also included are five wrappers which help in using old non-generic collections as generic collections. This could be helpful if you want to wrap a non-generic collection from an old application as generic ones in your application.
Like in .NET 1.1, there is need for a generic ISet in the .NET 2.0 environment. There are already some implementations based on JasonSmith's famous Iesi.Collections.ISet. One of them was found on NHibernate' JIRA which is, according to G77 (thanks!), authored by David Marquam. The implementation of this article is basically a modified version of that implementation. I would like to make it clear that most of the credit of this extension goes to him. I posted this version here so that more people can take advantage of this nice work.
However, David's implementation could not perfectly meet our needs because of several facts:
- The
ISet<T>in this implementation also inherits theISet. This inheritance caused the lost of the type safe characteristic that a generic collection normally has. - The
ISet<T>does not have thebool Add(T o)method like theISethas. It only has thevoid ICollection<T>.Add(T o); the ability to tell whether the item has been actually added might be missed. - The generic extension was included in the assembly of JasonSmith’s
Iesi.Collection, which makes some difficulty in working with the originalIesi.Collection.
Using the code
Thus I decided to modify this implementation so that the ISet<T> looks like the following:
public interface ISet<T> : ICollection<T>, ICloneable {…}In the meantime, I think it could be very helpful if the base Set class still implements the ISet interface since it has been widely applied, including by NHibernate. In this way, you can still have the collection mapped by NHibernate.
public abstract class Set<T> : ISet<T>, ISet {…}As a reminder, here is the declaration of ISet from Iesi.Collections:
public abstract class ISet : ICollection, ICloneable {…}For the usage of this ISet<T>, please refer to JasonSmith's article about his Iesi.Collections.
Since Set<T> brought the scenario where a generic collection needs to work with old non-generic collections, I added five simple wrappers:
public struct EnumeratorWrapper<T> : IEnumerator<T>{…}
public class EnumerableWrapper <T> : IEnumerable<T>
public sealed class SetWrapper<T> : ISet<T>
public class CollectionWrapper<T> : EnumerableWrapper<T>, ICollection<T>
public class ListWrapper<T> : EnumerableWrapper<T>, IList<T>These wrappers support using regular collections under a generic collection interface by wrapping the regular collection as an inner collection and delegate all the functions to it. Also, the Equals() of the wrapper are also overridden to delegate to the wrapped, so that wrapperA.Equals(wrapperB) will return true when and only when wrappedA.Equals(wrappedB) is true. The usage of these wrappers are very simple, here is a sample code:
IList = new ArrayList(3);
list.Add("one");
list.Add("two");
list.Add("three");
ICollection<string> cln = new CollectionWrapper<string>(list);
IEnumerable<string> enl = new EnumerableWrapper<string>(list);
IList<string> lst = new ListWrapper<string>(list);The Iesi.Collections.Generic is in an independent assembly so that use can have more flexibility with using this together with the Iesi.Collection.Generic.
I will keep working on the implementations since my development greatly relies on them.
Important Notes
- This implementation is based on the source code from NHibernate which does not override the
Equalsmethod, so thea.Equals(b)in this implementation will only returntrueifa==b;. - The generic
SynchornoizedSethas not been implemented yet.
Latest Update:
Feb 6, 06
I added the Iesi.Collections.Test from Nhibernate1.0.2.0. 67 out of the 87 tests were passed using the generic implementation.
The four ExclusiveOR tests could not be passed before I did a very minor modification to the original Iesi.Collections: in the original Set, the method ExclusiveOr was written as follows:
public static ISet ExclusiveOr(ISet a, ISet b)
{
if(a == null && b == null)
return null;
else if(a == null)
return (Set)b.Clone();
else if(b == null)
return (Set)a.Clone();
else
return a.ExclusiveOr(b);
}Note that the clones of a and b are unnecessarily down cast to Set. While, in the Union method of this class, these two clones are down cast to ISet. I modify the original code as follows:
return (ISet)b.Clone();
...
return (ISet)a.Clone();After this modification, the Iesi.Collection still passes all the Iesi.Collection.Test, and the generic implementation also passes the four ExclusiveOr tests.
Latest update: This small bug of Iesi.Collection.Set has been fixed in the NHibernate version 1.1-alpha1 [ 10081 ], so you don't need to worry about this problem if you are using Iesi.Collection from the later versions of NHibernate.
There are still 16 tests that cannot be passed. They are all operator tests. Since operators can only be used between classes not interfaces, the operator tests down cast the ISet to Set to do the tests, and our generic implementation cannot be downcast to the non-generic Set which causes the failure of the 16 tests.