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.  [ 11 posts ] 
Author Message
 Post subject: Need help with Nhiberate.Mapping.Attributes(in code mapping)
PostPosted: Mon Jan 01, 2007 6:53 pm 
Newbie

Joined: Mon Jan 01, 2007 6:18 pm
Posts: 11
Location: New Zealand
Hibernate version:

Build 1.0.3.0

Mapping documents:

hibernate.cfg.xml:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.0" >
  <session-factory name="NHibernate.Test">
    <!-- properties -->

    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string">Data Source=RICHARD\SQLEXPRESS;Initial Catalog=project1;Integrated Security=True</property>
    <property name="show_sql">true</property>
    <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>


    <property name="use_outer_join">true</property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    <!-- mapping files -->
    <mapping assembly="Com.Saliacorp.Project1.Business" />
  </session-factory>

</hibernate-configuration>


map.cs:

Code:
[NHibernate.Mapping.Attributes.Class(0, Name="Business.Map, Business", Table = "Map")]
public class Map
{
private int id;
private Image img;
private String title = "";

public Map()
{

}

[NHibernate.Mapping.Attributes.Id(1, Name="Id",Column="MapId", Type = "System.Int32", UnsavedValue="0")] // Don't put it after [ManyToOne] !!!
[NHibernate.Mapping.Attributes.Generator(2, Class = "increment")]
public int Id
{
get { return id; }
set { id = value; }
}

[NHibernate.Mapping.Attributes.Property(3, Name = "Image")]
[NHibernate.Mapping.Attributes.Column(4, SqlType = "image")]
public Image Image
{
get { return img; }
set { img = value; }
}

[NHibernate.Mapping.Attributes.Property(5, Name = "Title")]
public String Title
{
get { return title; }
set { title = value; }
}


Code between sessionFactory.openSession() and session.close():

I hope you can help

I am unable to find a demonstration of anyone who has got the Hibernate.Mapping.Attributes method of in code mapping to work. This library allows you to specify the mapping in the source code rather than in a .hbm.xml file. A slight demo of the code i am trying to get working is:



Configuration config = new Configuration();
// setup the config object with database connection and dialect settings

config.Configure(this.Server.MapPath(@".\Bin\hibernate.cfg.xml"));
//config.BuildSessionFactory();

NHMA.HbmSerializer serializer = new NHMA.HbmSerializer();
serializer.Validate = true; // optional

using( MemoryStream stream = new MemoryStream() )
{
serializer.Serialize( stream, Assembly.GetExecutingAssembly() );
stream.Position = 0;
config.AddInputStream( stream );
}

ISessionFactory m_SessionFactory = config.BuildSessionFactory();

ISession session = m_SessionFactory.OpenSession();

ITransaction tx = session.BeginTransaction();

Map map1 = new Map();

map1.Image = Image.FromFile(@"C:\dessusam8.gif");
map1.Title = "title1";
session.Save(map1);

tx.Commit();

session.CloseSession();





Full stack trace of any exception that occurs:

Doing this brings me up the following error:

NHibernate.MappingException: Unknown entity class: Business.Map
at NHibernate.Impl.SessionFactoryImpl.GetPersister(Type theClass)
at NHibernate.Impl.SessionImpl.GetClassPersister(Type theClass)
at NHibernate.Impl.SessionImpl.GetPersister(Object obj)
at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything)
at NHibernate.Impl.SessionImpl.Save(Object obj)
at Service.save() in c:\Inetpub\wwwroot\WebSite1\App_Code\Service.cs:line 69

This is the line that seems to throw the error but I have no idea what I am doing wrong?
session.Save(map1);

Name and version of the database you are using:

MSSQL Express 2005 (NOTE: i can get this to work if i use the .hbm.xml mapping file I just want to get this to work using incode mappings which are part of the nhibernate.mapping.attributes library.)


I feel that I am doing something wrong in either the business object or the session code.

Thanks in advance
Richard


Top
 Profile  
 
 Post subject: NHibernate.MappingException: Unknown entity class
PostPosted: Tue Jan 02, 2007 6:34 pm 
Beginner
Beginner

Joined: Tue Jan 02, 2007 5:53 pm
Posts: 42
Location: Bergen, Norway
Hi!

There must be something wrong in your mapping of the domain class. Are you sure that the database contains the table you have annotated in the class before you call save? I never experienced any such problems, and here is a simple example of what I did to get this working:

Code:
[Class(Table = "Locations")]
    public class Location : ILocation
    {
        protected long _primKey = 0;
        private string _loactionType;
       
        /// <summary>
        /// A default no-args constructor for NHibernate reflection.
        /// </summary>
        public Location() { }

       
        /// <summary>
        /// Gets the unique identifier of this object, surrogat key.
        /// </summary>
        [Id(Name = "PrimKey")]
        [Generator(1, Class = "native")]
        public virtual long PrimKey
        {
            get { return _primKey; }
            set { _primKey = value; }
        }

        /// <summary>
        /// The location type could be used as a discriminator value if
        /// an inheritence relationship between location related
        /// entities were to be used.
        /// </summary>
        [Property(NotNull = true)]
        public string LoactionType
        {
            get { return _loactionType; }
        }
    }


And in my HibernateConfiguration class I have the following method to persist all classes in the model assembly (this one is quite similar to yours):

Code:
        /// <summary>
        /// Initialize the configuration based on the provided assemblies of the persitable types.
        /// </summary>
        /// <param name="assembly">The assembly containing the implementations of the domain model concepts</param>
        protected void Initialize(Assembly assembly)
        {
            // Use NHibernate.Mapping.Attributes to create information about our entities
            MemoryStream stream = new MemoryStream(); // Where the information will be written in
            HbmSerializer.Default.Validate = true; // Enable validation (optional)
            // Ask to NHibernate to use fields instead of properties
            HbmSerializer.Default.HbmDefaultAccess = "field.camelcase-underscore";
            // Gather information from this assembly (can also be done class by class)
            Console.Out.WriteLine("NHibernate.Mapping.Attributes.HbmSerializer.Default.Serialize()...\n");
            //

            HbmSerializer.Default.Serialize(stream, assembly);
            stream.Position = 0;
            DumpHbmXmlStreamToFile(stream, hbmXmlDumpFile);
            stream.Position = 0;
            cfg.AddInputStream(stream); // Send the Mapping information to NHibernate Configuration
            stream.Close();
        }


I also dump the generated hbm.xml stream to file so that I can inspect the mappings created.

I hope this helps!

_________________
Cheers,
Steinar.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 02, 2007 7:24 pm 
Newbie

Joined: Mon Jan 01, 2007 6:18 pm
Posts: 11
Location: New Zealand
Thanks for the reply.

Is the code below what I would use to call that function of yours?

Code:
Initialize(Assembly.GetAssembly(typeof(Map)));


Where Map is the class I want to generate a mapping for. Currently from this code I am getting an error on the line with:

Code:
HbmSerializer.Default.Serialize(stream, assembly);


The error message is as follows:

Code:
System.NotSupportedException: This required value hasn't been provided!
Class: Business.MapObject
Member: Image
   at NHibernate.Mapping.Attributes.HbmWriterHelper.Get_Column_Name_DefaultValue(MemberInfo member)
   at NHibernate.Mapping.Attributes.HbmWriter.WriteColumn(XmlWriter writer, MemberInfo member, ColumnAttribute attribute, BaseAttribute parentAttribute)
   at NHibernate.Mapping.Attributes.HbmWriter.WriteProperty(XmlWriter writer, MemberInfo member, PropertyAttribute attribute, BaseAttribute parentAttribute)
   at NHibernate.Mapping.Attributes.HbmWriter.WriteClass(XmlWriter writer, Type type)
   at NHibernate.Mapping.Attributes.HbmSerializer.Serialize(Stream stream, Assembly assembly)
   at Service.Initialize(Assembly assembly) in c:\Inetpub\wwwroot\WebSite1\App_Code\Service.cs:line 50
   at Service.save() in c:\Inetpub\wwwroot\WebSite1\App_Code\Service.cs:line 99


Not sure if the following makes a difference but extra info can't hurt :)

I am working with multiple projects in the solution. I have a csharp library project for the business namespace and for executing tasks upon the business objects i am using a webservice. So essentially all code at the moment that is not (Map.cs) a business object is in the webservice.


MapObject is also a business object but i am not trying to map that at the moment. It should be ok with being mapped though as the code is complete for it. It is strange that the error references it even though it is independent from Map (for now).


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 02, 2007 8:50 pm 
Newbie

Joined: Mon Jan 01, 2007 6:18 pm
Posts: 11
Location: New Zealand
lol I have found where i was going off track. Disregard that last post this was the problem.


Code:
       
[NHibernate.Mapping.Attributes.Property(3, Name = "Image")]
        [NHibernate.Mapping.Attributes.Column(4, SqlType = "image")]
public Image Image
{
       get { return img; }
       set { img = value; }
}


any one know what is wrong with that mapping?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 02, 2007 9:00 pm 
Beginner
Beginner

Joined: Tue Jan 02, 2007 5:53 pm
Posts: 42
Location: Bergen, Norway
I am bulding n-tiered applications where my domin and business model resides in the middleware. If you're bulding webservices you probably desing along these principals as well.

My domain interfaces are defined in one project while all the implementations of these interfaces are defined in another. This way it is easy to resolve project dependencies and have the HibernateConfiguration module being unaware of which domain classes it will save, load, update or delete.

So, since I have several projects/modules I simply provide the HibernateConfiguration with the assembly information of my model. I retrieve the assembly like this:

Code:
using System.Reflection;

namespace Model.core
{
    public class ModelAssembly
    {
        private static ModelAssembly modelAssembly;
       
        public static ModelAssembly GetInstance()
        {
            if(modelAssembly == null) modelAssembly = new ModelAssembly();
            return modelAssembly;
        }

        private Assembly assembly = null;
       
        private ModelAssembly()
        {
            assembly = Assembly.GetExecutingAssembly();
        }
       
        public Assembly GetAssembly()
        {
            return assembly;
        }
    }
}


Providing the previous method with the assembly in this way should work, but then I presume you were enable to connect to the DB and that the rest of the HibernateConfiguration works. It should not be necessary for you to provide any other code to the HibernateConfigurator class then the model assembly the way shown here. If you try to use the Location class provided above then it should be able to be saved into the locations table.

Hope this helps!

_________________
Cheers,
Steinar.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 02, 2007 9:08 pm 
Beginner
Beginner

Joined: Tue Jan 02, 2007 5:53 pm
Posts: 42
Location: Bergen, Norway
I believe you must map to a blob type. Why not try something like: NHibernate.SqlTypes.BinaryBlobSqlType

Code:
[Property( Name = "Image", TypeType = typeof(BinaryBlobSqlType))]
public Image Image
{
       get { return img; }
       set { img = value; }
}

_________________
Cheers,
Steinar.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 04, 2007 12:05 am 
Newbie

Joined: Mon Jan 01, 2007 6:18 pm
Posts: 11
Location: New Zealand
Thanks heaps I have manged to construct a working example out of what you have provided. From this I will be able to work out where i was going wrong in my project.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 04, 2007 11:38 am 
Contributor
Contributor

Joined: Thu May 12, 2005 9:45 am
Posts: 593
Location: nhibernate.org
rhwilburn wrote:
Code:
       
[NHibernate.Mapping.Attributes.Property(3, Name = "Image")]
        [NHibernate.Mapping.Attributes.Column(4, SqlType = "image")]
public Image Image
{
       get { return img; }
       set { img = value; }
}

any one know what is wrong with that mapping?


If you read the beginning of the exception:
Code:
System.NotSupportedException: This required value hasn't been provided!
Class: Business.MapObject
Member: Image
   at NHibernate.Mapping.Attributes.HbmWriterHelper.Get_Column_Name_DefaultValue(MemberInfo member)


It is saying that you must provide a value for Name in the attribute [Column].
Eg:
Code:
       
[Property]
        [Column(1, Name = "Image", SqlType = "image")]
public Image Image
{
       get { return img; }
       set { img = value; }
}

_________________
Pierre Henri Kuaté.
Get NHibernate in Action Now!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 27, 2007 8:25 pm 
Newbie

Joined: Mon Jan 01, 2007 6:18 pm
Posts: 11
Location: New Zealand
Thanks for the previous help. I am having difficulty getting images from the database still. I have managed to use NHibernate and the class below to put them in the database but when i try the query mentioned towards teh bottom of this post I cannot retrive location objects. I can retrive them if the image is null (not set) but if it is i cannot retrive the object.

Code:
namespace Model
{
    [Class(Table = "Locations")]
    public class Location : ILocation
    {
        long _primKey = 0;
        string _name;
        Image _image;

        /// <summary>
        /// A default no-args constructor for NHibernate reflection.
        /// </summary>
        public Location() { }


        /// <summary>
        /// Gets the unique identifier of this object, surrogat key.
        /// </summary>
        [Id(Name = "PrimKey")]
        [Generator(1, Class = "increment")]
        public virtual long PrimKey
        {
            get { return _primKey; }
            set { _primKey = value; }
        }

        /// <summary>
        /// The name of the attraction
        /// </summary>
        [Property(NotNull = true)]
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        /// <summary>
        /// This attribute provides the image displayed, representing the location on the map the location belongs to.
        /// </summary>


        [Property(NotNull = true)]
            [Column(2, Name = "Image", SqlType = "image")]
        public Image Image
        {
            get { return _image; }
            set { _image = value; }
        }

    }
}


The code above produces the following mapping

Code:
<?xml version="1.0" encoding="utf-8"?>
<!--Generated from NHibernate.Mapping.Attributes on 2007-01-28 13:09:07Z.-->
<hibernate-mapping default-access="field.camelcase-underscore" xmlns="urn:nhibernate-mapping-2.0">
<class name="Model.Location, Model" table="Locations">
    <id name="PrimKey">
      <generator class="increment" />
    </id>
    <property name="Name" not-null="true" />
    <property name="Image" not-null="true">
      <column name="Image" sql-type="varbinary" />
    </property>
</class>
....


That code works fine when getting a Location from the database that doesn't have an image set. Ones that have an image set give the following error:

Code:
NHibernate.ADOException: Could not execute query ---> NHibernate.Type.SerializationException: Could not deserialize a serializable property:  ---> System.Runtime.Serialization.SerializationException: End of Stream encountered before parsing was completed.
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
   at NHibernate.Type.SerializableType.FromBytes(Byte[] bytes)
   --- End of inner exception stack trace ---
   at NHibernate.Type.SerializableType.FromBytes(Byte[] bytes)
   at NHibernate.Type.SerializableType.Get(IDataReader rs, Int32 index)
   at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name)
   at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String[] names, ISessionImplementor session, Object owner)
   at NHibernate.Type.AbstractType.Hydrate(IDataReader rs, String[] names, ISessionImplementor session, Object owner)
   at NHibernate.Loader.Loader.Hydrate(IDataReader rs, Object id, Object obj, ILoadable persister, ISessionImplementor session, String[][] suffixedPropertyColumns)
   at NHibernate.Loader.Loader.LoadFromResultSet(IDataReader rs, Int32 i, Object obj, Key key, String suffix, LockMode lockMode, ILoadable rootPersister, ISessionImplementor session)
   at NHibernate.Loader.Loader.InstanceNotYetLoaded(IDataReader dr, Int32 i, ILoadable persister, String suffix, Key key, LockMode lockMode, Key optionalObjectKey, Object optionalObject, IList hydratedObjects, ISessionImplementor session)
   at NHibernate.Loader.Loader.GetRow(IDataReader rs, ILoadable[] persisters, String[] suffixes, Key[] keys, Object optionalObject, Key optionalObjectKey, LockMode[] lockModes, IList hydratedObjects, ISessionImplementor session)
   at NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, IList hydratedObjects, Object optionalObject, Object optionalId, Key[] keys, Boolean returnProxies)
   at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Object optionalObject, Object optionalId, Object[] optionalCollectionKeys, Boolean returnProxies)
   at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Object optionalObject, Object optionalId, Object[] optionalCollectionKeys, Boolean returnProxies)
   at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
   at NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet querySpaces, IType[] resultTypes)
   at NHibernate.Hql.QueryTranslator.List(ISessionImplementor session, QueryParameters queryParameters)
   at NHibernate.Impl.SessionImpl.Find(String query, QueryParameters parameters)
   --- End of inner exception stack trace ---
   at NHibernate.Impl.SessionImpl.Find(String query, QueryParameters parameters)
   at NHibernate.Impl.QueryImpl.List()
   at NHibernate_Controller.HibernateConfiguration.Query(String queryStr) in C:\Visual_Studio_Projects\hibernate_advanced_example\Model\Hibernate_Controller\HibernateConfiguration.cs:line 84
   at Model.Query.MapDetails.GetMapObjects(Int32 mapId, String filter) in C:\Visual_Studio_Projects\hibernate_advanced_example\Model\Model\Query\MapDetails.cs:line 47
   at Service.GetMapObjects(String name, String country) in c:\Inetpub\wwwroot\Hibernate_Advanced_Example\App_Code\Service.cs:line 85


(irrelevant i think) The query i am using to get this is: "select l from location as l";

The file I put into the database was a gif file and the database being used is mssql2005

I have tried using varbinary(max) and using image as the database type but this did not seem to make a difference.

Thanks for any help in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 28, 2007 8:27 pm 
Newbie

Joined: Mon Jan 01, 2007 6:18 pm
Posts: 11
Location: New Zealand
I manged to fix the bug by changing a piece of the Location class.

Code:
[Property(NotNull = true, Type = "Byte[]")]
        [Column(2, Name = "Image", SqlType = "image")]
public Byte[] Image
{
        get { return _image; }
        set { _image = value; }
}


it appears that nhibernate doesn't support writing back to a csharp image type? as it was happy to serialize it but not to deserilize it; purhaps this needs to be addressed as a Jira issue?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 29, 2007 2:16 am 
Newbie

Joined: Mon Jan 29, 2007 2:03 am
Posts: 11
rhwilburn wrote:
I manged to fix the bug by changing a piece of the Location class.

Code:
[Property(NotNull = true, Type = "Byte[]")]
        [Column(2, Name = "Image", SqlType = "image")]
public Byte[] Image
{
        get { return _image; }
        set { _image = value; }
}


it appears that nhibernate doesn't support writing back to a csharp image type? as it was happy to serialize it but not to deserilize it; purhaps this needs to be addressed as a Jira issue?


hi rhwilburn,

Because there is no 1:1 mapping of CTS types against SQL types, example of this is the image type. ADO.NET/NH needs to (de)serialise the content thru an array of bytes. You can refer also to NH guide of NHibernate Types.

HTH


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