-->
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.  [ 7 posts ] 
Author Message
 Post subject: Mapping for a reference to an enumerated type
PostPosted: Thu Jan 24, 2008 9:54 am 
Beginner
Beginner

Joined: Sun Nov 18, 2007 10:39 am
Posts: 46
Location: Liverpool, England
I'm getting an error with a mapping, and I'm not sure what I'm doing wrong. I have a table Actions which contains a column ActionType. This links to a table ActionTypes, which is basically a look up table. I have an enum as follows:

Code:
Namespace Rules.DAO

Partial Public Class ActionTypeList

  Public Enum enActionType
    StoredProcedure = 1
    Program = 2
    EDI = 3
    Code = 4
  End Enum

  {...}


which is referred to by the mapped class Action as follows:

Code:
Namespace Rules.DAO

  protected _actionType As ActionTypeList.enActionType
  public Overridable Property ActionType As ActionTypeList.enActionType
    Get
      return _actionType
    End Get
    Set(ByVal value As ActionTypeList.enActionType)
      _actionType = value
    End Set
  End Property



From reading the NHibernate docs, I should map this as a standard property with a type of the fully qualified name of my enum, so I have the following in the map file for Action:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Rules.DAO" assembly="Rules.DAO">
  <class name="Rules.DAO.Action, Rules.DAO" table="Actions">
{...}
    <property name="ActionType" type="Rules.DAO.ActionTypeList.enActionType" />
{...}


When I try to create the session factory though I get the following error:

"could not interpret type: Rules.DAO.ActionTypeList.enActionType"

Can anyone tell me what I'm doing wrong? If I move the enum out of the class, and change the mapping accordingly it works, but I'd really prefer to have the enum defined within the class.

Kev


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 25, 2008 9:56 am 
Hibernate Team
Hibernate Team

Joined: Tue Jun 13, 2006 11:29 pm
Posts: 315
Location: Calgary, Alberta, Canada
Enums are treated in NHibernate as the underlying integral type (Int32 in most cases). Just remove the type= attribute from the mapping. i.e.:
Code:
<property name="ActionType"/>

_________________
Karl Chu


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 25, 2008 11:34 am 
Beginner
Beginner

Joined: Sun Nov 18, 2007 10:39 am
Posts: 46
Location: Liverpool, England
Excellent, that did the trick. I think the documentation is incorrect though, as that indicates you specify the type and namespace.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 25, 2008 12:52 pm 
Regular
Regular

Joined: Wed Jun 21, 2006 3:13 pm
Posts: 110
It doesn't look like you're specifying the assembly for your type.

Like this:

<property name="Status" column="Status" type="KennelFinder.KennelStatus, KennelFinder" />

I could be wrong, but I think you need something like:

<property name="ActionType" type="Rules.DAO.ActionTypeList.enActionType, {Your assembly here}" />


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 25, 2008 1:00 pm 
Beginner
Beginner

Joined: Sun Nov 18, 2007 10:39 am
Posts: 46
Location: Liverpool, England
Yes, you're right, sorry - the example I pasted in was one I'd been playing with. Even with the assembly specifed though, it still gave me the error. Omitting the type altogether resolves the problem. Also of note, my workaround of pulling the enum out of the class worked with the mapping as given.

Kev


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 25, 2008 1:21 pm 
Regular
Regular

Joined: Wed Jun 21, 2006 3:13 pm
Posts: 110
Ok, I think I figured it out with the help of Reflector.

Pull your assembly into reflector and you will see that your enum, because it's inside of the class, is qualified with a +

Here is my code. I apologize that it's in C# and not VB.NET, but I don't see why it wouldn't resolve the same for you:

Code:
namespace PersonRage
{
   public partial class Person
   {
      public enum PersonStatus
      {
         Alive,
         NotAlive
      }

      private int id;
      private string name;
      private PersonStatus status;
      
      public int Id
      {
         get { return id; }
      }
      
      public string Name
      {
         get { return name; }
         set { name = value; }
      }
      
      public PersonStatus Status
      {
         get { return status; }
         set { status = value; }
      }
   }
}


And my mapping:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
   <class name="PersonRage.Person, PersonRage" table="Person">
      <id name="Id" type="Int32" access="nosetter.camelcase" >
         <column name="personId" not-null="true" unique="true" />
         <generator class="native" />
      </id>
      
      <property name="Name" column="Name" />
      <property name="Status" column="Status" type="PersonRage.Person+PersonStatus, PersonRage" />
   </class>
</hibernate-mapping>


Of note, my type is PersonRage.Person+PersonStatus, PersonRage and not PersonRage.Person.PersonStatus, PersonRage as I would have expected. Please note the plus sign between Person and PersonStatus.

My test code, which worked rather well:

Code:
         DbSessionContext.Current.OpenSession();

         Person bob = new Person();

         bob.Name = "Bob Smith";
         bob.Status = Person.PersonStatus.Alive;

         DbSessionContext.Current.Save(bob);
         
         DbSessionContext.Current.CloseSession();

         DbSessionContext.Current.OpenSession();

         Person bobAgain = DbSessionContext.Current.Get<Person>(bob.Id);

         Console.WriteLine(bobAgain.Status.ToString());
         DbSessionContext.Current.CloseSession();
         


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 28, 2008 8:44 am 
Beginner
Beginner

Joined: Sun Nov 18, 2007 10:39 am
Posts: 46
Location: Liverpool, England
Yes, that makes sense. Without the plus I guess there would be ambiguity between a namespace Person containing a PersonStatus and a class Person containing a PersonStatus. I'll modify my templates accordingly

Cheers,
Kev


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