Chander Dhall's Blog

Sponsors

Tags

Nhibernate: Component set to null if all component columns are null

This post is in regards to the post I saw unanswered on Nhibernate forums since Mon Feb 12, 2007 1. 

When reloading the containing object, Hibernate will assume that if all component columns are null, then the entire component is null.

If you dive through the source code it occurs somewhere here.

1. if (ReturnedClass.IsValueType)

2. return values;

3. else

4. return notNull ? values : null;

Easy(but not advisable) solution is to alter source code like this.

   return values. (removed lines 1, 3 and 4 above).

 

This solution is not advisable as with every version change in Nhibernate you will have to recode this piece(if, in case, if it not fixed by the team :) ).

That's not the end to it. This could be fixed if we create a custom interceptor and override a method called OnLoad(). However, later in class TwoPhaseLoad it again changes the component object to null at the following line.

 persister.SetPropertyValues(entity, hydratedState, session.EntityMode);

For test purposes I am using Northwind database.

The solution is below. However, this solution is beneficial only if you are trying to implement a custom interceptor. If not, go to the bottom of the post.

public class Customer

{

virtual public string CustomerId

{ get; set; }

virtual public string CompanyName

{ get; set; }

virtual public Address Address{ get; set; }

 

}

 

public class Address

{

virtual public string City

{ get; set; }

virtual public string Region{ get; set; }

}

 

Customer.hbm.xml file:

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

assembly="NhibTest" namespace="NhibTest">

<class name="Customer" table="Customers">

<id name="CustomerId" type="string">

 

</id>

<property name="CompanyName" />

<component name="Address">

<property name="City"/>

<property name="Region"/>

</component>

</class>

  </hibernate-mapping>

 nhibernate.cfg.config file:

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">

<session-factory>

<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>

<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>

<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>

<property name="connection.connection_string">Data Source=ggrubbs\sqlexpress;Initial Catalog=Northwind;Integrated Security=True</property>

<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>

//Please make sure you add this line.

<property name="show_sql">true</property>

<property name="generate_statistics">true</property>

</session-factory>

</hibernate-configuration>

MyInterceptor.cs

public class MyInterceptor : EmptyInterceptor

{

private ISessionFactory _sessionFactory;

private ISession _session;

private object _entity;public MyInterceptor(ISessionFactory sessionFactory)

{

_sessionFactory = sessionFactory;

}

 //Overriding this method also solves the problem.public virtual void AfterTransactionCompletion(ITransaction tx)

{

var stats = _session.Statistics;

var sessionImplementor = _session.GetSessionImplementation();

IPersistenceContext persistenceContext = sessionImplementor.PersistenceContext;

EntityEntry entityEntry = persistenceContext.GetEntry(_entity);for (int i = 0; i < entityEntry.LoadedState.Length; i++)

{

if (entityEntry.Persister.PropertyTypes[i].IsComponentType && entityEntry.Persister.PropertyNames[i].Equals("Address"))

{

if (_entity != null && _entity is Customer)

{

if ((_entity as Customer).Address == null)

{

(_entity
as Customer).Address = new Address();

}

}

}

}

}

}

 

Program.cs file:

_configuration = new Configuration();

_configuration.Configure();

_configuration.AddAssembly(
typeof(Customer).Assembly);

_sessionFactory = _configuration.BuildSessionFactory();

 

ISession session = _sessionFactory.OpenSession(new MyInterceptor(_sessionFactory));

There is also a very easy way of solving this problem.
Just make sure you add the following check in your component types.

protected Address _address;virtual public Address Address

{

get { return _address ?? (_address = new Address()); }

set { _address = value; }

Please let me know if you need the VS 2010 project. Please leave your email in the comment fields.


Fluent Nhibernate No persister for: <ClassName>

I got this error while working on the following class.   

   internal partial class OrganizationMap : ClassMap<Organization>
    {
        #region constructors
        internal OrganizationMap()
        {
            Id(x => x.OrganizationId).GeneratedBy.Assigned();
            Map(x => x.DateCreated).Generated.Always();
            Map(x => x.DateUpdated).Generated.Always();
            Map(x => x.VersionNumber).Generated.Always();
            Map(x => x.UUID);
            Map(x => x.Name);
       }

 }

 Here is the code I used to test it.

 var sessionFactory = CreateSessionFactory();

            using (var session = sessionFactory.OpenSession())
            {

                using (var transaction = session.BeginTransaction())
                {
                    var newOrganization = new Organization
                    {
                        OrganizationId = 150,
                        Name = "Organization 150",
                    
                        UUID = Guid.NewGuid()
                    };

                    //LINE THAT BREAKS
                    session.Save(newOrganization);
                    session.Flush(); //force the SQL INSERT
                    session.Refresh(newOrganization); //re-read the state (after the trigger executes)
                 

                    transaction.Commit();

                 
                }

In case of Nhibernate, mostly this error occurs if the hmb.xml is not marked as 'Embedded Resource'.

Solution: This error occurs since the class is not public. Just change the class to public and this won't occur again. However, if you do not want to expose the assembly outside the Assembly you can still mark the constructor as 'internal'. 

The only downside to it is that the class shows up in intellisense. However, you would get a compile time error if you try to use it.  So, I guess that works.

Truly speaking this would fix any logical errors but I don't personally like the idea of the classes being forced to have the access modifiers of public. 

Composition vs Aggregation

Composition and aggregation both are different forms of association. If an association is more like a 'is a' relationship, both of these are more like a 'has a' relationship. It is more like a whole/part relationship or an owner/owned relationship. For example, an automobile has an engine or the other way round, engine is 'a part of' an automobile. What's the difference?

 Composition is a higher degree of association than aggregation. The only major difference in terms of objects is the management of lifetime of the objects. In case of composition the lifetime of the owned object is the responsibility of the owner object.

 For example.

public class Person

{

  public string FirstName {get; set;}

  public string FirstName {get; set;}

  public Address CompleteAddress {get; set;}

}

 

public static void Main()

{

         Person person = new Person();

         person.CompleteAddress = new Address();

         //This line explains that it is a composition as the lifetime of CompleteAddress object depends on the person object.

        //The moment 'person' is garbage collected, the CompleteAddress object is also garbage collected.
}

 

Let's take another example for Aggregation

public void Car

{

     public string VIN { get; set; }

     public Engine MyEngine { get; set; }

     public Car(Engine engine)

     {

           this.MyEngine = engine;

     }

}

 

Now let's call it in Main.

public static void Main()

{

      Engine engine = Engine.GetEngine();

      //Just gives us an object. We could have 'newed' it also. However, a good place to inject dependency.

      Car car = new Car(engine);

      // 'engine' object here does not depend on the lifetime of the 'car' object.

      // So it is a case of aggregation.

     // However, car.MyEngine is an example of composition.

     // Most of the times when we code, we do something like Car car = new Car(new Engine());

     // In this case, we do not retain the Engine object as it is created in the constructor call/

     // That is the case when people start getting confused between aggregation and composition.

}

 In UML, the symbol for aggregation is a quadrilateral more like a rhombus which is unfilled and for composition it a filled rhombus.

 Hope that helps.

Asp.Net MVC2 and Azure - Dallas Tech Fest

It was great presenting at Dallas Tech Fest on Asp.Net MVC on Azure.  However, this is the dilemma I have to go through unfortunately still. In a show of hands before the talk starts I still find majority of the audience not knowing about either of the technologies. So, I have to make my talk more dynamic so that I don't keep the audience guessing. This usually takes the talk in a direction that is really good for most of them. However, for the ones who know both I always run short of time to cover everything I had. In this talk, it was fun explaining how the partitioning guidelines for Azure Table Storage. I shall blog about it soon as I had a good feedback about the guidelines and it was pointed out that my recommendations have not been made on the web by others. That will be my first web contribution since I have been contributing only through talks and want to start reaching out a wider audience.

Best Comment I received was from Chris Rajczi "Our team had looked into Azure few months ago and decided not to go with it. After attending your presentation we have decided to go for it."

 I have a talk on Azure Best practices tonight at Microsoft Campus, las colinas. 

DataServiceRequestException was unhandled by user code. An error occurred while processing this request.

Make sure you please read the previous blog post on StorageException otherwise this would not make sense. Once we change the code in the constuctor and forget to change the table name this exception would occur. This exception occurs usually when

1. you do not have the table name which you are requesting. This could occur if you try to delete something and try to access it concurrently from some other thread. Or if you do not have the table with the same name in your storage.

2. You may just have the name there in the form of 'Emailaddress' and you are accessing it with a similar name which is CamelCased for example, 'EmailAddress'. 

DataServiceRequestException was unhandled by user code
 An error occurred while processing this request.

 If you follow the post from the previous post, this exception occurs at a different place. Even though the solution is same, the exception is different and hence somewhat misleading. The exception occurs at the save changes line and the user would normally think that the AddObject function ran well.

    public void AddEmailAddress(EmailAddressEntity emailAddressTobeAdded)
        {

            AddObject("EmailAddress", emailAddressTobeAdded);
            SaveChanges();

        }

 However, avoid the naming of the EmailAddress in the AddObject method as CamelCasing.  So changing it to "emailaddress" or "Emailaddress" fixes it. Again, it could be some other factors owing to which this exception might occur.At the time of writing this post, I had seen difference in the 32-bit environment and 64-bit environment so please cross check this. Feel free to email me the code and i shall be happy to help.

Exception of type 'Microsoft.WindowsAzure.StorageClient.StorageClientException' was thrown.

Sometimes even if we have the fabric running and the role manager is up, we get an exception of this sort.  

The code breaks at the line in BOLD.


public EmailAddressDataContext(CloudStorageAccount account) :
            base(account.TableEndpoint.AbsoluteUri, account.Credentials)
        {
            this.storageAccount = account;

            CloudTableClient emailAddressClient =
                new CloudTableClient(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
            emailAddressClient.CreateTableIfNotExist("EmailAddress");
        }

 

Easy fix is to change EmailAddress to Emailaddress. For some reasons it would not allow CamelCasing. So please make sure, you just have one capital letter in the name of the table that too at the beginning. Since the table names are case insensitive, you can also name it as 'emailaddress' . However, make sure that you do not access it with a different case. Follow the next post to have a better idea of what I am suggesting.

3P's (Principles, patterns and performance) of Software Development Dallas Dot Net User Group.

 I recently presented this talk on Jun 9th at Microsoft Offices, Las Colinas. This talk dives deep into the algorithmic analysis and problem solving to get the best preformance using the powerful C# language. It focussed specifically on improving performance on Asp.Net websites. It talks about YDN guidelines to make your websites perform faster.
At the same time techniques to demonstrate how to write modular code without affecting performance were shown. I shall be blogging separately on these topics pretty soon.

Please feel free to leave comments. I am not sure how to upload ppts on the blog as I am new to this. However, I shall be uploading the presentations as soon as I am able to do it. 

Azure Table Storage C# Sig Dallas July 1st, 2010.

 Tonight I presented at Improving Offices, Dallas. It was a great crowd with some really good questions on Azure. This talk went from Introduction of Azure Table Storage to the best practices in Windows Azure. We discussed the guidelines for addressing the issues of limited provision of indexing in Azure. I shall be blogging on it pretty soon as I don't think there is enough insight currently on partitioning data well.

You can download the Presentation Code here.

Shawn will be putting the talk on his website in video format. I shall update the link then.

Azure Table Storage Austin Code Camp

Just moved to my new blog. I am trying to upload all my presentations here starting from Austin Code Camp, this year. For presentations earlier to this, please email me or follow links at twitter @csdhall.

This presentation covers a talk about fundamental data abstractions in Windows Azure, an in-depth discussion about the power and capabilities of Azure, best practices related to it. It includes scalability vs batch processing guidelines and outlines the different approaches suiting the new business needs. Demos were on introduction to tables, queuue and blobs in Windows Azure. Azure is a great platform for start ups and with security been taken seriously in the cloud it actually is supposed to grow leaps and bounds. Since Microsoft has done it right and is putting a lot of money and talent into it, I am sanguine that it will take over a greater share of market in next couple of months.

 You can listen to the talk at Austin Code Camp talk 

 

 

 

More Posts « Previous page