Ayendes post is a great start how it should be designed.
It will perfectly work for enterprise solutions. The names in a separate table is like any other list of values. The special thing is, that it is filtered in the mapping.
Edit - Options:
Use another entity to edit the data
There is Product entity that has all the names as list. LocalizedProduct has only the current languages name.
Get the filtered entity
- by either mapping it as described in the blog, with the filter.
- by selecting it with a result transformer (Transformers.AliasToBean) or with 'select new LocalizedProduct(id, name, prize ...)'. LocalizedProduct would not be mapped in this case. Should be second-level-cache-friendly.
If you have many references to Product, it is probably not so nice to have two classes, because you don't know which class the reference should have.
Use the same entity for editing and displaying
class Product
{
string LocalizedName
{
get { return AllProductNames[Thread.CurrentThread.CurrentCulture.LCID]; }
}
IDictionary<int, string> AllProductNames { get; private set; }
}
There are properties for a localized product name (get) and all product names.
- don't filter them at all :-) There is a bit of network overhead. if you have only 3 to 5 languages, it is not so bad. if you have 20 or more, it's probably better to filter the names.
- use a (optional) filter as described in the blog, but on the product names
- use a (optional) ResultTransformer (CriteriaUtil.AliasToEntityMap) to filter the names.
To be honest, I would choose a option that dies not need filters in the mapping files. Filters belong to queries where they are more maintainable.