在Hibernate中,如何自动检索父ID并将其作为外键用于子插入?

时间:2014-10-16 08:36:40

标签: java hibernate many-to-one

我想要的操作:如果需要,在子表中插入一行会自动在父表中插入一行,否则使用父表中现有行的id作为插入行中的外键儿童桌。

我想知道是否有办法在hibernate中使用单个session.save(child)语句执行上述操作。

我正在使用Hibernate与Java和SQLite。 以下是我对数据库和配置的具体细节:

表父:

{id (int): primary key, description (text): unique}

表儿童:

{id(int): primary key, address (text), parent_id (integer): foreign key refers Parent(id)}  [UNIQUE ( address, parent_id )]

POJO家长:

{int id, String description, Set<Child> children, [getters and setters] }
POJO孩子:

{int id, String address, Parent parent, [getters and setters]}

Parent.hbm:

...
<id column="id" name="id" type="long">
    <generator class="native"/>
</id>
<property column="description" name="description" type="string" unique="true" />
<set fetch="select" inverse="true" lazy="true" name="children" table="Child">
    <key>
        <column name="parent_id" not-null="true"/>
    </key>
    <one-to-many class="Child"/>
</set>
...

Child.hbm:

....
<id column="id" name="id" type="long">
    <generator class="native"/>
</id>
<property column="address" name="address" type="string"/>
<many-to-one cascade="save-update" class="Parent" fetch="select" name="parent">
    <column name="parent_id" not-null="true"/>
</many-to-one>
...

截至目前,如果父母(具有相同的&#39;描述&#39;)不存在,则父母与子女一起插入。否则,因为父插入失败而未插入子节点,因为它具有唯一的描述&#39;需求。

由于我在插入子节点时不知道父节点的id(我只知道父节点的描述),所以我无法执行session.load(Parent.class,parentId)来检索父对象并使用它插入孩子。我现在正在做的是:

Parent parent = new Parent();
parent.setDescription("D1");

Child child = new Child();
child.setAddress("A1");

parent.getChildren().add(child);
child.setParent(parent);
session.save(child);

我知道我总是可以通过执行查询select id from Parent where description="D1"来查找父ID,然后如果结果集为空,则保存子项,因为我现在正在执行它(也插入父项),并且如果结果不为空,请使用session.load()加载父对象并使用它来插入子对象。但我认为hibernate可以在一个session.save(child)后面为我处理。可以吗?

1 个答案:

答案 0 :(得分:0)

尝试以下步骤;

1.更改您的Parent.hbm

 ...
<id column="id" name="id" type="long">
    <generator class="native"/>
</id>
<property column="description" name="description" type="string" unique="true" />
<set fetch="select" inverse="true" lazy="true" name="children" table="Child" cascade="save-update">
    <key>
        <column name="parent_id" not-null="true"/>
    </key>
    <one-to-many class="Child"/>
</set>
...

2.更改您的Child.hbm

....
<id column="id" name="id" type="long">
   <generator class="native"/>
</id>
<property column="address" name="address" type="string"/>
<many-to-one class="Parent" fetch="select" name="parent">
    <column name="parent_id" not-null="true"/>
</many-to-one>
...

3.根据需要在父母之前添加孩子

Parent parent = new Parent();
parent.setDescription("D1");

Child child = new Child();
child.setAddress("A1");
child.setParent(parent);

session.save(child);
Set<Child> childsSet = new HashSet<Child>();
childsSet.add(child);

parent.setChildren(childsSet);
session.save(parent);