sql - Localizable strings in JPA -
to solve need localized dynamic (user created, stored in db) data in java ee 6 project, made general localized string table capable of storing string in language. avoid having make ~15 tables containing names stuff. know 2 things:
1) think good or bad idea, , why? 2) know know of clean solution issue listed under cons?
my experiences:
pros: 1 table needed, general solution easy configure both in jpa , db. duplicated code nonexistant.
cons: big issue find due muiltilingual_string table knowing objects using it, cascade deletes won't work sql (but works in jpa orphanremoval). produces possibilities "dead" strings remain in database if worked outside jpa.
the entities: (abstractentity mapped superclass containing @id , @version)
@entity @table(schema = "competence", name = "multilingual_string") public class multilingualstring extends abstractentity{ @elementcollection(fetch=fetchtype.eager) @mapkey(name = "language") @collectiontable(schema = "competence", name = "multilingual_string_map", joincolumns = @joincolumn(name = "string_id")) private map<language, localizedstring> map = new hashmap<language, localizedstring>(); public multilingualstring() {} public multilingualstring(language lang, string text) { addtext(lang, text); } public void addtext(language lang, string text) { map.put(lang, new localizedstring(lang, text)); } public string gettext(language lang) { if (map.containskey(lang)) { return map.get(lang).gettext(); } return null; } public localizedstring getlocalizedstring(language lang){ if(map.get(lang) == null) map.put(lang, new localizedstring(lang, null)); return map.get(lang); } @override public multilingualstring clone(){ multilingualstring ms = new multilingualstring(); for(localizedstring s : map.values()) ms.addtext(s.getlanguage(), s.gettext()); return ms; } @override public string tostring() { return getid() == null ? "null " + this.getclass().getname() : getid().tostring(); } } @embeddable public class localizedstring { @joincolumn(name="lang_id") private language language; @column(name="text") private string text; public localizedstring() { } public localizedstring(language language, string text) { this.language = language; this.text = text; } public language getlanguage() { return language; } public void setlanguage(language language) { this.language = language; } public string gettext() { return text; } public void settext(string text) { this.text = text; } }
the classes used following in other entities:
@onetoone(cascade=cascadetype.all, orphanremoval=true) @joincolumn(name = "summary_stringid") private multilingualstring summary;
the tables:
multilingual_string ( id bigint primary key ); multilingual_string_map ( string_id bigint foreign key references multilingual_string(id), lang_id bigint foreign key references lang(id), text varchar(2000 char), primary key(string_id, lang_id) );
are used following:
competence ( id bigint primary key, name_id bigint foreign key references multilingual_string(id) );
one question see not seem work cascading of resourcebundle.
in resourcebundle, if locale es_es, first localized version in es_es, if not find try in es , if not, default string (in case fails show #string_id string). have .en dictionary, .en_uk expressions particular united kingdom, , .en_us expressions particular us, , in en_uk , en_us put keys needed.
with system, looks @ current locale without allowing of these options, have redefine values each locales. so, in above example, have put value each key both en_uk , en_us.
Comments
Post a Comment