2
votes

Hi guys I'm a new to NHibernate. I just started development of my next project using NHibernate. One of the requirements is that entity classes should be localized. I'm doing localization the following way: - Every entity which should be localized is split into 2 table and 2 entities. For example, I have an entity Service which holds some information, and another entity ServiceLocale which holds localized properties, such as Name, description etc. Same goes for tables.

  • Service has a protected field which holds a list of ServiceLocales. ServiceLocale has a property Culture which specifies which language the object belongs.

  • The list of ServiceLocale is loaded eagerly from xml mapping file. So when Service is loaded from database, all ServiceLocales also is loaded for this service object.

  • Service has public properties, Name and Description. From this properties, I check what's current culture, load appropriate ServiceLocale object and return ServiceLocale's Name and Description.

  • Service is persisted using a repository. The repository checks saves or updates the service, and also all of it's ServiceLocale objects.

So my question is: is there a better way to achieve this kind of transparent localization via NHibernate? Thanks

1

1 Answers

1
votes

Ok guys, for whom whos interested in answer, I have one. Jason Meckley wrote me about the solution on nhibernate newsgroup. Looks like it's best to use nhibernate filters. Here's his answer:

if you mean to load all the locals any time you query the primary entity, that's a preformance problem waiting to happen. now it may work if you introduce a filter which can be set right after the session opens. this way only a single result is returned per localized resource. it would also bleed into your domain model.

//class
private ISet<string> localizedvalues;
public string Value{get{return localizedvalues.FirstOrDefault();}}

//mapping
<class name="myentity">
   <set name="localizedvalues" access="field" lazy="false" join="fetch">
         <filter name="CultureFilter" />
         ...
   </set>
</class>
<filter-def name="CultureFilter" condition="cultureId = :culture">
   <param name="culture" type="string" />
</filter-def>

//session configuration
var session = factory.Open();
session.EnableFilter("CultureFilter").SetParameter("culture", Thread.CurrentThread.CurrentCulture.LCID);

this is similar to how ayende's examples works, except we are using a set instead of a formula to pull the locale.