Sunday, October 1, 2023
No menu items!
HomeCloud ComputingNHibernate Dialect for Cloud Spanner is now Generally Available

NHibernate Dialect for Cloud Spanner is now Generally Available


Do you have an application that you developed with NHibernate and now you want to migrate to a cloud database? Google Cloud Spanner now supports the NHibernate Object Relational Mapper. You can reuse existing NHibernate code with the Cloud Spanner NHibernate dialect, or write new features while leveraging existing knowledge.

The Cloud Spanner NHibernate dialect implements all the classes and interfaces that are needed to use Cloud Spanner with NHibernate. Add the Spanner NHibernate nuget package to your project and connect to Cloud Spanner as follows:


Install the Spanner NHibernate dialect:

dotnet add package Google.Cloud.Spanner.NHibernate –version 1.0.0


Connect to Cloud Spanner with NHibernate:

code_block[StructValue([(u’code’, u’using NHibernate;rnusing NHibernate.Cfg;rnrnConfiguration = new Configuration().DataBaseIntegration(db =>rn{rn db.Dialect<SpannerDialect>();rn db.ConnectionString =rn “Data Source=projects/MY-PROJECT/instances/MY-INSTANCE/databases/MY-DATABASE”;rn});rnvar sessionFactory = Configuration.BuildSessionFactory();rnusing var session = configuration.SessionFactory.OpenSession();rnrnvar transaction = session.BeginTransaction();rnvar singer = new Singerrn{rn FirstName = “Jamie”,rn LastName = “Allison”rn};rnawait session.SaveAsync(singer);rnawait transaction.CommitAsync();’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3ef1dfcf7a90>)])]

You can also use a custom connection provider or a user supplied connection with Spanner NHibernate. See this example for more information.


The Cloud Spanner NHibernate dialect supports standard NHibernate features, like querying data using both the NHibernate Criteria API and Linq, managing associations and executing transactions. The dialect also supports specific Spanner features such as interleaved tables, mutations and stale reads.

Query with Linq

NHibernate 3.0 introduced the Linq to NHibernate provider. The Spanner NHibernate dialect implements translations for the most commonly used functions and operators so these can be used with LInq.

code_block[StructValue([(u’code’, u’using var session = configuration.SessionFactory.OpenSession();rnrnvar singersBornBefore2000 = await sessionrn .Query<Singer>()rn .Where(s => s.BirthDate < new SpannerDate(2000, 1, 1))rn .OrderBy(s => s.BirthDate)rn .ToListAsync();rnConsole.WriteLine(“Singers born before 2000:”);rnforeach (var singer in singersBornBefore2000)rn{rn Console.WriteLine($”\t{singer.FullName}, born at {singer.BirthDate}”);rn}rnrnvar singersStartingWithAl = await sessionrn .Query<Singer>()rn .Where(s => s.FullName.StartsWith(“Al”))rn .OrderBy(s => s.LastName)rn .ToListAsync();rnConsole.WriteLine(“Singers with a name starting with ‘Al’:”);rnforeach (var singer in singersStartingWithAl)rn{rn Console.WriteLine($”\t{singer.FullName}”);rn}’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3ef1dfb8d4d0>)])]

Interleaved Tables

Using interleaved tables for parent-child relationships in your schema can improve performance. Interleaving a child table with a parent means that the child records will be stored physically together with the parent. These relationships can be modeled and used as any other association in NHibernate.

code_block[StructValue([(u’code’, u’using var session = configuration.SessionFactory.OpenSession();rnusing var transaction = session.BeginTransaction();rnrn// Create a Singer, Album and Track.rn// Album references Singer with a normal foreign key relationship.rnvar singer = new Singerrn{rn FirstName = “Farhan”,rn LastName = “Edwards”,rn};rnvar album = new Albumrn{rn Title = “Thinking Jam”,rn Singer = singer,rn};rn// Track is interleaved in Album. This means that Track must use a composite primaryrn// key. In this example, the primary key is the Album ID and a Track number.rnvar track = new Trackrn{rn // A TrackIdentifier consists of the parent Album and a track number.rn TrackIdentifier = new TrackIdentifier(album, 1L),rn Title = “Always Sweet”,rn};rnawait session.SaveAsync(singer);rnawait session.SaveAsync(album);rnawait session.SaveAsync(track);rnawait transaction.CommitAsync();’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3ef1dfb8d990>)])]

This directory contains the complete mapping of all the entities that are used in the sample above.


NHibernate will use Data Manipulation Language (DML) by default. You can instruct NHibernate to use mutations for all transactions that are executed using a specific NHibernate session, or for a single transaction.

code_block[StructValue([(u’code’, u’var sessionFactory = configuration.Configuration.BuildSessionFactory();rnrn// Create a session that will always use mutations.rnusing var session = sessionFactoryrn .OpenSession()rn .SetBatchMutationUsage(MutationUsage.Always);rnrn// Create a new Singer and save it. The insert will use a Mutation.rnvar transaction = sessionUsingMutations.BeginTransaction();rnvar singer = new Singerrn{rn FirstName = “Wanda”,rn LastName = “Yates”,rn};rnawait session.SaveAsync(singer);rnawait transaction.CommitAsync();rnrn// You can also instruct a single transaction to use mutations.rnusing var session2 = sessionFactory.OpenSession();rnvar transaction2 = session.BeginTransaction(MutationUsage.Always);’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3ef1dfb8dfd0>)])]

Further Samples

The GitHub repository contains a directory with multiple samples for common use cases for working with NHibernate and/or Cloud Spanner. 


Cloud Spanner features that are not supported in NHibernate are listed here.

Getting Involved

We’d love to hear from you, especially if you’re a .NET developer considering Cloud Spanner or an existing Cloud Spanner customer who is considering using NHibernate for new projects. The project is open-source, and you can comment, report bugs, and open pull requests on Github.

Cloud BlogRead More



Please enter your comment!
Please enter your name here

Most Popular

Recent Comments