#hibernate #composite-key
#спящий режим #составной ключ
Вопрос:
Хорошо, итак, у меня есть 2 объекта, родительский и дочерний. Дочерний элемент в основном выглядит так:
public class Child implements Serializable
{
// primary (composite) key
private int parentId;
private String name;
// random value
private String val;
public Child(String name, String val) {
this.name = name;
this.val = val;
// note: parentId is not assigned a value
}
public void setParentId(int id) {
[...]
}
В основном я хочу, чтобы спящий режим автоматически устанавливал родительский идентификатор дочернего элемента после создания родительского объекта. Возможно ли это или мне нужно добавлять дочерние объекты к родительскому объекту после сохранения родительского объекта в базе данных?
Отображение xml родительского элемента выглядит так:
`<map name="children" inverse="true" lazy="true" cascade="all,delete-orphan">
<cache usage="nonstrict-read-write"/>
<key column="parent_id"/>
<index column="child_name" type="string"/>
<one-to-many class="myPack.Child"/>
</map>`
и XML дочернего элемента:
<hibernate-mapping package="myPack">
<class name="Child" table="child_tbl" lazy="true">
<composite-id>
<key-property name="ParentId" type="int" column="parent_id"/>
<key-property name="Name" column="name" type="string"/>
</composite-id>
<property name="Val" blablabla
[...]
Комментарии:
1. Итак, ваша проблема была решена? Я не вижу ни принятого ответа, ни каких-либо комментариев.
2. В итоге я перебрал все дочерние элементы в DAO после сохранения родительского объекта и установки их родительской ссылки. Не то, что я изначально хотел сделать, но, думаю, это работает так же хорошо…
Ответ №1:
Если вы хотите, чтобы спящий режим вставлял родительский дочерний элемент вместе с внешним ключом, используйте сопоставление объектов, а не идентификаторы.
Давайте возьмем пример отсюда,
public class AMain {
//Properties of A.
List<ASub3> subList;
.....
}
public class ASub3 {
.....
AMain parent;
.....
}
в hbm.xml файл в AMain добавить,
<list name="subList" inverse="true" cascade="all" lazy="false">
<key column="a_id" />
<list-index column="as3_id" />
<one-to-many class="com.manu.hibernate.mappings.domain.ASub3" />
</list>
в Asub3 добавить,
<many-to-one name="parent" class="com.manu.hibernate.mappings.domain.AMain"
column="a_id" unique="true" cascade="save-update" />
Теперь в клиентском коде используйте компоненты, как показано ниже,
AMain a = new AMain("A");
ASub3 as3a = new ASub3("List - 1");
ASub3 as3b = new ASub3("List - 2");
ASub3 as3c = new ASub3("List - 3");
as3a.setParent(a);
as3b.setParent(a);
as3c.setParent(a);
List<ASub3> subList = new ArrayList<ASub3>();
subList.add(as3a);
subList.add(as3b);
subList.add(as3c);
a.setSubList(subList);
Теперь, если вы сохраните AMain, оба AMain и ASub3 будут обновлены (я имею в виду соответствующую таблицу) с помощью внешнего ключа для AMain.
Ответ №2:
Привет, за несколько дней до того, как я столкнулся с такой же проблемой. У меня есть решение в классах аннотаций. Поскольку у меня нет вашего родительского класса, позвольте мне высказать свое предположение
public class Parent implements Serializable
{
// Id is generated by sequence so it is not assigned when parent will be created
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_APP")
@SequenceGenerator(name="SEQ_APP",sequenceName="SEQ_APP")
private Integer id;
private String name;
@ManyToMany
@JoinTable(
name = "CHILD_TABLE",
joinColumns = { @JoinColumn(name = "PARENT_ID")},
inverseJoinColumns = {@JoinColumn(name = "NAME")}
)
@Cascade(CascadeType.DELETE_ORPHAN)
private Set<Child> childs= new HashSet<Child>();
// getters and setters
}
public class Child {
// primary (composite) key
private int parentId;
private String name; }
Комментарии:
1. это не сопоставление xml