Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> multilanguage models (hibernate) 
:(
    Опции темы
gelo86
Дата 20.1.2010, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Например у меня есть много моделеи (до 30) каторые имеют поле name. Но так как ета програма дла несколких языков, то в модели есть такие поля:
Код

class Product {
     private String nameRu;
     private Strng nameEn;
     ....
}

А если мне надо добавить есчо адин язык ? Хочется держат тексты гдето оддельно. Но где ? В оддельной таблице думал, но тогда при стартупе придется грузить до 500.000 строк (для 3 языков). Да и как потом их использовать? В йсп я должен изпользовать чтото типо ${product.name} и оно должно вывести то name, для которого включена локаль. Как ви решали или решили би подобную проблему ?
PM MAIL   Вверх
powerOn
Дата 21.1.2010, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Для начала можно почитать вот эту доку. А в целом нужно смотреть на решения по интернационализации предоставляемые вашим фреймворком. В сущности такие поля не добавляют.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
gelo86
Дата 21.1.2010, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Использю Spring 3.0 MVC, но както ненахожу, что могбы в нем использовать для речения своеи проблемы.
PM MAIL   Вверх
serger
Дата 21.1.2010, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 19.6.2007
Где: Ижевск

Репутация: 2
Всего: 5



а зачем в базе хранить разные поля для каждого языка?


--------------------
упс!
PM MAIL WWW Skype GTalk Jabber   Вверх
afon
Дата 21.1.2010, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 5.4.2008
Где: Украина, Киев

Репутация: нет
Всего: 1



i18n со своими бандлами не решает проблему интернационализации хранимых объектов.. имхо.
Тут надо мутить какую-то связь. Так, если по-быстрому, то я бы сделал так: 
Цитата


@Entity
public class Product {

 name;
 price;
 ...
 
@OneToMany
 Set<ProductLanguages> languages;

}


Цитата

@Entity
public class ProductLanguages {
 @Column(unique = true, nullable = false)
 private languageName;
 
 productName; 

 @ManyToOne
 product;
}


А дальше, получается, когда тебе нужно вынуть, к примеру, перевод продукта на хранцузском, делаешь 

Цитата

franchProduct = ProductLanguagesDAOImpl.findByLang("fr", product);
franchProduct.getproductName()


ну и сам метод 
Цитата

findByLang(langName, product) {
  query = "from ProductLanguages pl where pl.languageName = ? and pl.product = ?"
  return getHibernateTemplate().find(query, new Object[] {langName, product});
}


Это то, что пришло в голову самое первое. А вообще, наверное, есть и другие варианты. Можно сделать и более гибкий и более абстрактный объект LanguageTranslation, в который можно было бы забрасывать совершенно разные объекты... думать надо
PM MAIL WWW   Вверх
gelo86
Дата 21.1.2010, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Неахота писать для 30 моделеи есчо 30 ModelNameLanguages (вет ето есчо 30 таблиц в базе данных).


Цитата(afon @  21.1.2010,  13:54 Найти цитируемый пост)
ожно сделать и более гибкий и более абстрактный объект LanguageTranslation

Ето вы имели ввиду, чтобы был какойто сервис ? Да ето возможн, с ДАО получаеш лист обектов, подаеш в некий сервис и он записывает в поле модели name имя по включенной локали (например селетит из одной таблицы перевод для всех моделеи).

А может както возможо с hibernate interceptor, hibernate custom user type ?

Добавлено через 57 секунд
Цитата(serger @  21.1.2010,  13:34 Найти цитируемый пост)
а зачем в базе хранить разные поля для каждого языка? 


А как иначе ?
PM MAIL   Вверх
serger
Дата 21.1.2010, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 19.6.2007
Где: Ижевск

Репутация: 2
Всего: 5



Цитата(gelo86 @  21.1.2010,  14:05 Найти цитируемый пост)
Цитата(serger @  21.1.2010,  13:34 Найти цитируемый пост)
а зачем в базе хранить разные поля для каждого языка? 


А как иначе ? 

Вы меня не поняли, ну и ладно, теперь зато я понял.  smile 


--------------------
упс!
PM MAIL WWW Skype GTalk Jabber   Вверх
powerOn
Дата 21.1.2010, 19:03 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Мне честно говоря тяжело представить задачу, где нужно интернационализировать сущности... Обычно такая операция относится к заголовкам страниц, служебной информации, всякие там лицензионные соглашения, надписи на кнопках.. Но что бы имя, пусть того же, продукта...  А как пользователь будет вынужден создавать такой продукт? Вводить название на всех языках или только на том с какой локали он работает? А что если нет выбранной локали в БД? Тут предстоит учесть не мало мелочей. 


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
gelo86
Дата 21.1.2010, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Цитата(powerOn @  21.1.2010,  19:03 Найти цитируемый пост)
А как пользователь будет вынужден создавать такой продукт? Вводить название на всех языках или только на том с какой локали он работает


Нет, он сначала выберает, кокого типа продукт он создает.  Так вот ети типы и можно через админ редактировать. А усер просто видет каталог типов продуктов с именами в его локали.

Цитата(powerOn @  21.1.2010,  19:03 Найти цитируемый пост)
А что если нет выбранной локали в БД

Усер в интерфейсе сможет выберать толко те локали, которые запрограммированные в программе.

PM MAIL   Вверх
powerOn
Дата 21.1.2010, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



В таком случае, думаю, вам придется реализовывать логику управления  такими сущностями самостоятельно. 
Например создать класс для хранения локализованного значения имени и сделать связь коллекции таких имен с вашим продуктом.
Код

class LocalizedName {
    private String locale;
    private String name;
}

class Product {
    private List<LocalizedName> localizedNames;
}

Может быть имеет смысл использовать Map вместо List. В общем такая логика будет находиться под ответственностью вашего приложения, фреймворк, увы, не сможет взять её на себя.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
gelo86
Дата 21.1.2010, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Я тоже пришел к такоу решению, толка в продукте хранить название для самой употребляемой локали, например если сайт написант для росии, то хронить руское название (90% усерав будут использовать например), а отдельно названия на других языках (чтоб небыло много джоинов, тем самым улутшим перформанц).

Но мне неохота создавать для каждой сущности по отдельной таблице. Думаю создать чтото такого:

Код

Translations {
    private String clazzName;  // а может Class clazzType ?
    private long objectId;
    private String nameEn;
    private String nameFr;
    ...
}


Только как потом примапить с Hibernate'ом в сущность product, все переводы где clazzName='Product' и objectId = ид продукта, чтобы било чтото такого:
Код

class Product {
   private long id;
    private List<Translations> translations;
}
 

Как описать такой маппинг с hibernate. Притом в Translations маппинга наверно небудет, так как его будет использовать много сущностей.







PM MAIL   Вверх
afon
Дата 22.1.2010, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 5.4.2008
Где: Украина, Киев

Репутация: нет
Всего: 1



Вчера еще возникло похожее решение, но не успел отписаться. По-моему, оно будет более гибкое. 


Код

public class TranslatableObject {
    private Locale locale;
    private String simpleClassName;
    private Long objectId;
    private String fieldName;
    private String fieldTranslation;
}


В базе будет получаться что-то вроде такого
Код

ru    Product    4589    name    Цветочек
en    Product    4589    name    Flower


Таким образом можно переводить значения любых полей любого объекта. Относительно любого, конечно. 

Если очень хочется связей, чтобы дергать product.getTranslations(), то самым простым вариантом будет создать базовый класс, в котором прописать маппинг на TranslatableObject, и унаследовать от него все свои 30 хранимых объектов. Получится всего 2 дополнительных таблицы в базе. Код примерно такой

Код

@Entity
public class TranslatableObject {
    private Long id;
    private Locale locale;
    private String simpleClassName;
    private Long objectId;
    private String fieldName;
    private String fieldTranslation;
    @ManyToOne
    private BaseTranslatable baseTranslatable;
}

@MappedSuperclass
public class BaseTranslatable {
    private Long translatableId;

    @OneToMany
    private Set<TranslatableObject> translations;
}
   


Но мне кажется, что лучше обойтись без мапинга. Проще будет, не будет проблемы lazy collections и всего такого. Просто заюзать TranslatableObject, Locale и какой-нибудь TranslatableObjectDao.




Это сообщение отредактировал(а) afon - 22.1.2010, 13:55
PM MAIL WWW   Вверх
gelo86
Дата 22.1.2010, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Цитата(afon @  22.1.2010,  13:52 Найти цитируемый пост)
Но мне кажется, что лучше обойтись без мапинга. Проще будет, не будет проблемы lazy collections и всего такого.


А в чем заключается проблема lazy collections ? Я как понимаю, если есть маппиг, то ненадо будет самому писать селекты минус один дао. А по перформацу, то какя раазница или я руками или хибернате выташит ети данные ?
PM MAIL   Вверх
gelo86
Дата 22.1.2010, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Да и подумал, что так просто примапить мы несможет, так как фореигн кей будет неуникалным - в каждой таблице (из моих 30) может быть запись с ид=10. То если в TranslatableObject записать objectId=10, то етот TranslatableObject приампится для каздой сушности с ид=10. Я думаю надо будет дополнительно селектить и указывать simpleClassName. А после селектита создавать DTO обьект. Только получается что мне надо иметь сервис каторый будет трансформировать из хибернате обьекта в DTO и который поселектит переводы и запишет в DTO. 

Такчто сценарий такой:
1. Селектим хибернате обьекты из DAO.
2. С поможю сервиса конвертируем результат в DTO.

Как вам идея ? Какая критека ? smile
PM MAIL   Вверх
afon
Дата 22.1.2010, 22:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 5.4.2008
Где: Украина, Киев

Репутация: нет
Всего: 1



Критека канткретная  smile  читать то, что вы пишите, очень трудно. Так что уж потрудитесь...
А по сути: да дальше уже ваша собственная фантазия и конкретные прикладные проблемы все сделают. Мапить или нет, на какой id, сделать ли какой-то глобальный JoinTable верхнего уровня... зависит от  самого проекта. Дальше даже советовать трудно, не зная области... .

Это сообщение отредактировал(а) afon - 25.1.2010, 12:14
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0612 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.