Как использовать гибернацию с пользовательскими типами полей, которые отображаются на разные базы данных?

#java #hibernate #spring

#java #гибернация #весна

Вопрос:

Я работаю с проектом, в котором мне нужно сохранить объект в гибернации, и он состоит из множества пользовательских объектов. Я знаю, как использовать отображение гибернации с объектом, который содержит только «обычные» типы (int, String и т. Д.), Но с пользовательскими типами я видел такие предложения, как использование аннотации @embedded и реализация UserType, но я не видел никаких предложений о том, как просто сопоставить объекты внутри объектав определенную таблицу. Примечание: эти объекты не собираются в одной таблице, только в одной БД. Что я хочу сделать, так это иметь сопоставление, которое позволяет использовать эту функцию в моей реализации DAO:

 public void store(MyObject o){
hibernateTemplate.saveOrUpdate(o);
}
  

Это не похоже на то, как выглядит мой объект:

 public class MyObject{

private String name;

private ObjectA type;//Contains an int

private ObjectC look;//Contains a String.

private ObjectB[] children;//contains a string and other children.

public MyObject(){}

//Getters and setters omitted.

}

public class ObjectB{
private String name;
private ObjectB[] children;

public ObjectB(){}
//Getters setters omitted
}
  

Ответ №1:

Если содержимое какого-либо объекта необходимо сохранить в отдельной таблице, то этот объект должен быть другим постоянным объектом, и вы должны использовать ассоциации между объектами: OneToMany, ManyToOne, OneToOne, ManyToMany, в зависимости от мощности.

Прочитайте справочное руководство по гибернации.

Комментарии:

1. Я пытался это сделать, но есть одна проблема. Должно ли у дочернего элемента быть поле, в котором хранится родительский элемент? Посмотрите на этот пример: mkyong.com/hibernate/hibernate-one-to-many-relationship-example Это выглядит хорошо, но проблема в том, что у Stock есть несколько StockDailyRecords, но у StockDailyRecord должно быть поле Stock. Выглядит уродливо для меня, и в моем текущем проекте мне не разрешено добавлять поля в классы. Есть идеи по обходному пути? Не видел никого в руководстве.

2. Дочерним объектам не обязательно иметь поле с родительским (конечно, для таблицы, в которую они сопоставлены, по-прежнему требуется столбец с родительским идентификатором). Просто не указывайте отношение «один ко многим» в родительском классе как обратное.

3. @why_vincent: то, что вы хотите, — это однонаправленное отношение OneToMany. И в руководстве есть примеры такой взаимосвязи. Внимательно прочитайте это.

Ответ №2:

Вы должны написать обычное сопоставление объектов для класса ObjectB (так же, как вы сопоставляете MyObject), сопоставить его с выбранной вами таблицей и определить отношение «один ко многим» между MyObject и ObjectB. saveOrUpdate сохраняет переданный объект и все его поля, поэтому массив ObjectB также будет сохранен.

Что касается ObjectA или ObjectC, вы можете либо реализовать UserType, либо пометить их как @Embedded (если вы хотите, чтобы их поля были в той же таблице, что и поля MyObject), либо сопоставить их как объекты с другой таблицей (как в случае ObjectB).

Комментарии:

1. Поскольку они не принадлежат к одной таблице, мне пришлось бы использовать UserType, но тогда, на мой взгляд, красивый код гибернации начнет выглядеть плохо, и я мог бы также использовать Spring / JDBC.

2. Если они не принадлежат к одной таблице, не утруждайте себя написанием UserType, просто сопоставьте все объекты как сущности с разными таблицами, укажите отношения, и все должно работать нормально.