Спящий режим — автоматически назначать внешний ключ дочернему?

#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