Hibernate - 当在另一个类中 fk 自引用时处理添加(插入)

发布于 2024-11-09 04:55:49 字数 3582 浏览 0 评论 0原文

我的 Hibernate 配置如下。

CPUModel

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="org.example.CPUModel" table="cpu_model">
    <id name="cpuModelId" type="java.lang.Integer" unsaved-value="null">
      <column name="cpu_model_id"/>
      <generator class="identity"/>
    </id>
    <property name="name" type="java.lang.String">
      <column length="32" name="name"/>
    </property>
    <set name="softwares" inverse="true" lazy="false" table="cpu_model_software" cascade="all-delete-orphan" order-by="cpu_sw_id desc">
      <key>
        <column name="cpu_model_id" not-null="true"/>
      </key>
      <one-to-many class="org.example.CPUModelSoftware"/>
    </set>
  </class>
</hibernate-mapping>

CPUModelSoftware

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="org.example.CPUModelSoftware" table="cpu_model_software">
    <composite-id name="cpuModelSoftwarePK" class="org.example.CPUModelSoftwarePK">
      <key-property name="cpuModelId" column="cpu_model_id" type="java.lang.Integer"/>
      <key-property name="cpuSwId" column="cpu_sw_id" type="java.lang.Integer"/>
    </composite-id>
    <many-to-one class="org.example.CPUSoftware" insert="false" update="false" fetch="select" name="cpuSw">
      <column name="cpu_sw_id" not-null="true"/>
    </many-to-one>
  </class>
</hibernate-mapping>

选择值并更新可以正常使用此配置,但插入全新的值却行不通。

我收到此错误:

DEBUG Could not execute JDBC batch update [insert into exampledb.cpu_model_software (cpu_model_id, cpu_sw_id) values (?, ?)]
java.sql.BatchUpdateException: Column 'cpu_model_id' cannot be null

所以 Hibernate 试图在不首先从数据库生成 cpu_model_id 的情况下进行插入,然后将其设置为 CPUModelSoftwarePK (请参阅 CPUModel Hibernate 配置)

那么我如何告诉 Hibernate 它应该首先向 cpu_model 表进行插入。然后从那里获取 id 并设置 CPUModelSoftwarePK 的 id 并进行插入?

CPUModelSoftware/PK 的数据库如下。

+----------------+---------+------+-----+---------+-------+
| Field          | Type    | Null | Key | Default | Extra |
+----------------+---------+------+-----+---------+-------+
| cpu_model_id   | int(11) | NO   | MUL | NULL    |       |
| cpu_sw_id      | int(11) | NO   | MUL | NULL    |       |
+----------------+---------+------+-----+---------+-------+

对于 CPUModel

+----------------+------------------+------+-----+---------+----------------+
| Field          | Type             | Null | Key | Default | Extra          |
+----------------+------------------+------+-----+---------+----------------+
| cpu_model_id   | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| name           | varchar(32)      | NO   |     |         |                |
+----------------+------------------+------+-----+---------+----------------+

编辑

似乎我在制作新的 CPUModelSoftware 时没有将 CPUModelSoftwarePK 设为 null。但是现在我得到了这个:

ids for this class must be manually assigned before calling save(): org.example.CPUModelSoftware

I have Hibernate configs as follows.

CPUModel:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="org.example.CPUModel" table="cpu_model">
    <id name="cpuModelId" type="java.lang.Integer" unsaved-value="null">
      <column name="cpu_model_id"/>
      <generator class="identity"/>
    </id>
    <property name="name" type="java.lang.String">
      <column length="32" name="name"/>
    </property>
    <set name="softwares" inverse="true" lazy="false" table="cpu_model_software" cascade="all-delete-orphan" order-by="cpu_sw_id desc">
      <key>
        <column name="cpu_model_id" not-null="true"/>
      </key>
      <one-to-many class="org.example.CPUModelSoftware"/>
    </set>
  </class>
</hibernate-mapping>

CPUModelSoftware

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="org.example.CPUModelSoftware" table="cpu_model_software">
    <composite-id name="cpuModelSoftwarePK" class="org.example.CPUModelSoftwarePK">
      <key-property name="cpuModelId" column="cpu_model_id" type="java.lang.Integer"/>
      <key-property name="cpuSwId" column="cpu_sw_id" type="java.lang.Integer"/>
    </composite-id>
    <many-to-one class="org.example.CPUSoftware" insert="false" update="false" fetch="select" name="cpuSw">
      <column name="cpu_sw_id" not-null="true"/>
    </many-to-one>
  </class>
</hibernate-mapping>

Selecting values and updating works fine with this config, but inserting a completely new value just doesn't.

I get this error:

DEBUG Could not execute JDBC batch update [insert into exampledb.cpu_model_software (cpu_model_id, cpu_sw_id) values (?, ?)]
java.sql.BatchUpdateException: Column 'cpu_model_id' cannot be null

So Hibernate is trying to make an insert without first getting generated cpu_model_id from the DB, and setting then it for CPUModelSoftwarePK (see CPUModel Hibernate config)

So how do I tell Hibernate that it should first make an insert to cpu_model table. Then get the id from there and set the id for CPUModelSoftwarePK and make insert?

The db for CPUModelSoftware/PK is as follows.

+----------------+---------+------+-----+---------+-------+
| Field          | Type    | Null | Key | Default | Extra |
+----------------+---------+------+-----+---------+-------+
| cpu_model_id   | int(11) | NO   | MUL | NULL    |       |
| cpu_sw_id      | int(11) | NO   | MUL | NULL    |       |
+----------------+---------+------+-----+---------+-------+

and for CPUModel

+----------------+------------------+------+-----+---------+----------------+
| Field          | Type             | Null | Key | Default | Extra          |
+----------------+------------------+------+-----+---------+----------------+
| cpu_model_id   | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| name           | varchar(32)      | NO   |     |         |                |
+----------------+------------------+------+-----+---------+----------------+

EDIT

It seems that I wasn't nulling CPUModelSoftwarePK when making a new CPUModelSoftware. However now I am getting this:

ids for this class must be manually assigned before calling save(): org.example.CPUModelSoftware

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小…红帽 2024-11-16 04:55:49

据我了解,Hibernate 不支持 hbm.xml 中定义的映射中的派生标识。这意味着 Hibernate 无法根据 CPUModelCPUModelSoftware 之间的关系自动设置 cpuModelId 的值。

因此,您需要先保存CPUModel(带有空软件),然后需要将其生成的标识符分配给CPUModelSoftware的字段compisite id,并保存CPUModelSoftware

As far as I understand, Hibernate doesn't support derived identities in mappings defined in hbm.xml. It means that Hibernate can't set value of cpuModelId automatically based on relationship between CPUModel and CPUModelSoftware.

Thus, you need to save CPUModel (with empty softwares) first, then you need to assign its generated identifier to the field of CPUModelSoftware's compisite id, and save CPUModelSoftware.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文