<oops - I just realized I posted this to NHibernate instead of Hibernate - If there's a way to move it, please let me know.>
We've run into an issue related to the localization of data which an exhaustive search of these forums shows is not unique. The best description of the problem is this post:
http://forum.hibernate.org/viewtopic.php?t=966338
But these other posts also point at it:
http://forum.hibernate.org/viewtopic.php?t=964933
http://forum.hibernate.org/viewtopic.php?t=949110
http://forum.hibernate.org/viewtopic.php?t=939360
There seems to be general confusion about how to approach this. I've been able to solve it problem, but it requires two inelegant compromises which I'd prefer to avoid:
1) I have to change my Java class model by creating a superfluous class to store locale-related information.
2) I have to model this superfluous class as an entity in order to get the query semantics I want using Criteria. (It really should be modeled as a value because it's strictly contained within the life of its parent entity, but I was having trouble using criteria queries with restrictions on collections. See
http://hibernate.org/117.html#A2 for more information on this.)
I have an Account object which has some localized properties (e.g. name) and some non-localized properties (e.g. account number).
Java Class
Code:
public class Account {
private long accountNumber;
private String name;
private String description;
}
Schema (I don't want to change this. It's right.)Code:
ACCOUNT
=======
ID long, (PK)
ACCOUNT_NUMBER long
ACCOUNT_LOCALE
==============
ID long (PK)
ACCOUNT_ID long (FK)
LOCALE string
NAME string
DESCRIPTION string
Ideally, I would preserve the above class and schema and use the following syntax:
Code:
Account.getAccountNumber();
Account.getName(Locale);
I've not been able to find a way to do this (I've looked at interceptors, UserTypes, playing with the mapping file etc.)
My current approach (the one I referred to as inelegant) is to create an extra class to hold all properties that are localized, and to restructure my account class to add a map called "locales" which is keyed on the locale string, and has the value of this other class:
Code:
public class Account {
private long accountNumber;
private Map locales;
}
public class AccountLocale {
private String name;
private String description;
}
I then use a map collection in my .hbm and everything works alright.
But it requires an awkward syntax that breaks the original design of my POJO:
Code:
Account.getLocales("en_us").getName();
And owing to the aforementioned problem with criterias and collections, it's inconvenient to run queries. The most common query I'll run is to return all Account Objects for a given locale. And the most efficient way to do this is to do a single join betwen ACCOUNT and ACCOUNT_LOCALE, which is not easy: In fact, the best way to do it is to extend AccountLocale from Account and then use AccountLocale as the base from which to query using HQL.
Bottom line: I feel that owing to some inexperience with Hibernate, I've had to construct some inelegant hacks to solve this problem, and I'm looking for guidance on alternative approaches. Or perhaps I've done as well as I'm going to do, and I should move on.
By the way, I'm new to Hibernate and very impressed. Thanks to the creators!