NHibernate Forge
The official new home for the NHibernate for .NET community

Configuration and mapping

Article
Comments (5)
History (6)
100% of people found this useful

Configuration and mapping

Dialect Configuration:

  • In the NHibernate section of your configuration file add the following entry:
<property name="dialect">NHibernate.Spatial.Dialect.SomeSpatialDialect,SomeSpatialAssembly</property>
<add key="dialect" value="NHibernate.Spatial.Dialect.SomeSpatialDialect,SomeSpatialAssembly" />


Replace SomeSpatialDialect by the spatial dialect to be used (eg. MsSql2008SpatialDialect.) and SomeSpatialAssembly by the assembly name where it is located (eg. NHibernate.Spatial.MsSql2008)

Schema Generation Configuration:

  • Declarative: Use of <database-object> element is not supported.
  • Programmatic:    
    Configuration cfg = new Configuration();
    // Your configuration code (eg. cfg.Configure(); )
    cfg.AddAuxiliaryDatabaseObject(new SpatialAuxiliaryDatabaseObject(cfg));
    
    


Then you can use a SchemaExport object or the hibernate.hbm2ddl.auto configuration property for schema generation.

ActiveRecord Schema Generation Configuration:

You will need to add the SpatialAuxiliaryDatabaseObject in the Application_OnStart:

 using NHibernate.Cfg;
using NHibernate.Spatial.Mapping;

public void Application_OnStart()
{
foreach (Configuration cfg in ActiveRecordMediator.GetSessionFactoryHolder().GetAllConfigurations())
{
cfg.AddAuxiliaryDatabaseObject(new SpatialAuxiliaryDatabaseObject(cfg));
Metadata.AddMapping(cfg, MetadataClass.GeometryColumn);
Metadata.AddMapping(cfg, MetadataClass.SpatialReferenceSystem);
}
}

You can then generate the database schema in the usual way.

 

Metadata Mappings Configuration:

There are two classes available for metadata mapping in the NHibernate.Spatial.Metadata namespace: GeometryColumn and SpatialReferenceSystem. You can add them selectively:

Configuration cfg = new Configuration();
// Your configuration code (eg. cfg.Configure(); )
Metadata.AddMapping(cfg, MetadataClass.GeometryColumn);
Metadata.AddMapping(cfg, MetadataClass.SpatialReferenceSystem);


Then you can use them as normal mapped classes. For example, you could execute the following HQL query:

select srs.WellKnownText from SpatialReferenceSystem as srs where srs.SRID=4326


WARNING: DO NOT add metadata class mappings when using the SchemaExport utility. You could lose all contents of metadata tables.

NHibernate Mapping:

  • In the XML mappings file, map all properties as usual but for geometry columns use the following entry:
<property name="Geometry" column="the_geom" type="NHibernate.Spatial.Type.GeometryType, NHibernate.Spatial" />

 

  • Optionally, for schema generation and default values setting, you can use type parameters. The available parameters are srid and subtype. For example:
<property name="Geometry" column="the_geom">
<type name="NHibernate.Spatial.Type.GeometryType, NHibernate.Spatial">
<param name="srid">4326</param>
<param name="subtype">POLYGON</param>
</type>
</property>

 

  • In the mapped class, declare the corresponding property:
private GeoAPI.Geometries.IGeometry _geometry; 
public virtual GeoAPI.Geometries.IGeometry Geometry
{
get
{
return this._geometry;
}
set
{
this._geometry = value;
}
}

 

ActiveRecord Mapping:

 

private GeoAPI.Geometries.IGeometry _geometry; 

[Property("the_geom", ColumnType = "NHibernate.Spatial.Type.GeometryType, NHibernate.Spatial")]
public virtual GeoAPI.Geometries.IGeometry Geometry
{
get
{
return this._geometry;
}
set
{
this._geometry = value;
}
}


NOTE: Type parameters (see NHibernate mapping above) are not supported in ActiveRecord.

ActiveWriter Mapping:

ActiveWriter is a tool to visually model entities and relationships, and generate ActiveRecord classes or NHibernate mapping files. Since Preview 3, it supports custom types, so we can use the GeometryType / IGeometry pair..

Example usage:

  • Drag & drop a MsSqlSpatial table from Server Explorer/Data connections.
  • In the model, select "the_geom" property.
  • In the properties window, enter the following values:

<tbody> <tbody> </tbody> </tbody> <tbody> </tbody>

PropertyValue
Column Type Custom
Custom Column Type NHibernate.Spatial.Type.GeometryType, NHibernate.Spatial
Custom Member Type GeoAPI.Geometries.IGeometry

NOTE: Type parameters (see NHibernate mapping above) are not supported in ActiveRecord, so it is in ActiveWriter.

Recent Comments

By: Gripenstedt Posted on 04-08-2011 11:14

Hi everyone,

I am trying to do the same thing as is described above using Fluent NHibernate and I am having some troubles getting it to work. The database is an SQL Server 2008 R2. My little sample code currently looks like this.

Property

public virtual IGeometry GeometryColumn

{

get;

set;

}

Mapping

           Table("TestTabell");

           Schema("dbo");

           Id(x => x.Id).GeneratedBy.Native();

           Not.LazyLoad();

           Map(x => x.GeometryColumn).CustomType<GeometryType>();

Configuration

           var cfg = Fluently.Configure()

              .Database(MsSqlConfiguration.MsSql2008

                            .ConnectionString(_connectionString)

                            .ProxyFactoryFactory(

                                "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle")

               //.Dialect(

               //    "NHibernate.Spatial.Dialect.MsSql2008SpatialDialect,NHibernate.Spatial.MsSql2008")

              )

              .Mappings(m => m.FluentMappings.AddFromAssemblyOf<TestTabell>());

           //.ExposeConfiguration(c => c.AddAuxiliaryDatabaseObject(new SpatialAuxiliaryDatabaseObject(c)));

           Configuration configuration = cfg.BuildConfiguration();

           ISessionFactory sessionFactory = configuration.BuildSessionFactory();

Am I supposed to set the dialect and if so, what is the correct dialect string? Do I have to expose configuration and "AddAuxiliaryDatabaseObject"? I do not know and I would really appreciate some help.

I googled a lot and I always seem to find contradictory information regarding this.

I am thankful for any help I can get.

By: FredL Posted on 11-14-2010 14:50

For PostGis, the dialect path is:

<property name="dialect">

NHibernate.Spatial.Dialect.PostGisDialect,NHibernate.Spatial.PostGis

</property>

By: reddy Posted on 05-19-2009 18:01

You get this error "There is already an object named" because for some reason drop sql failed to drop an existing object and createsql is trying create that object again.

So you may want to cleanup your existing schema objects manually and try again.

RR

By: patgannon Posted on 02-12-2009 0:29

The code snippet under "ActiveRecord Schema Generation Configuration" didn't work for me.  Has this code been tested with the new version of NHibernate Spatial (built with NH 2.0.1)?  When my code called Metadata.AddMapping(cfg, MetadataClass.SpatialReferenceSystem) (in the code snippet), the following exception was thrown:

NHibernate.MappingException: Resource not found: NHibernate.Spatial.Metadata.SpatialReferenceSystem.MsSql2008SpatialDialect.hbm.xml

at NHibernate.Cfg.Configuration.LogAndThrow(Exception exception)

at NHibernate.Cfg.Configuration.AddResource(String path, Assembly assembly)

at NHibernate.Spatial.Metadata.Metadata.AddMapping(Configuration configuration, MetadataClass clazz) in C:\Projects\NHibernate.Spatial\trunk\src\NHibernate.Spatial\src\NHibernate.Spatial\Metadata\Metadata.cs: line 63

at ... (my code)

Am I missing a mapping file for the SQL 2008 spatial dialect?  (I didn't see one in the code.)  I'm not quite sure what "SpatialReferenceSystem" is, or why I need it, so I tried commenting out that line of code (but left in the other call to AddMapping which maps MetadataClass.GeometryColumn), since the geometry column type is the only one that I really need a special mapping for.  Unfortunately, when I call ActiveRecordStarter.CreateSchema(), the following unhandled exception is thrown:

MapBehavior : FailedSystem.Data.SqlClient.SqlException: There is already an object named 'NHSP_GEOMETRY_COLUMNS' in the database.

at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)

at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)

at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)

at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)

at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async)

at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)

at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()

at NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Boolean script, Boolean export, Boolean format, Boolean throwOnError, TextWriter exportOutput, IDbCommand statement, String sql)

at NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Boolean script, Boolean export, Boolean justDrop, Boolean format, IDbConnection connection, TextWriter exportOutput)

at NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Boolean script, Boolean export, Boolean justDrop, Boolean format)

NHibernate.HibernateException: There is already an object named 'NHSP_GEOMETRY_COLUMNS' in the database.

at NHibernate.Tool.hbm2ddl.SchemaExport.Execute(Boolean script, Boolean export, Boolean justDrop, Boolean format)

at NHibernate.Tool.hbm2ddl.SchemaExport.Create(Boolean script, Boolean export)

at Castle.ActiveRecord.ActiveRecordStarter.CreateSchema() in c:\Projects\Castle\ActiveRecord\Castle.ActiveRecord\Framework\ActiveRecordStarter.cs: line 261

Castle.ActiveRecord.Framework.ActiveRecordException: Could not create the schema

at Castle.ActiveRecord.ActiveRecordStarter.CreateSchema() in c:\Projects\Castle\ActiveRecord\Castle.ActiveRecord\Framework\ActiveRecordStarter.cs: line 265

at ...(my code)

Note that the NHSP_GEOMETRY_COLUMNS table does not exist prior to calling CreateSchema(), but it does exist after the exception is thrown.  Interestingly enough, it does actually create my table correctly with the geometry column (rather than creating that column as a 'tinyint', which was the case before I added in the aforementioned code snippet).

Any guidence you can provide would be greatly appreciated.

Thank you!

Pat Gannon

By: santoshamb Posted on 10-18-2008 5:19

For anybody (like me) new to NHibernate and NHibernate.Spatial, you'll need to import

NHibernate.Spatial.Mapping

in order to build with a reference to the SpatialAuxiliaryDatabaseObject

View All
Powered by Community Server (Commercial Edition), by Telligent Systems