java - 使用 Oracle 在 Hibernate 中插入多对一行时出现问题

标签 java oracle hibernate hibernate-mapping

我在使用 Hibernate 4.3.5 将父记录和关联子记录插入 Oracle 11g 数据库时遇到问题。我有一个 Record 类,其中包含一组 Image 对象。

记录类映射:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.wts.service.model.Record" table="RECORDS">
        <id name="recordId" type="long">
            <column name="REC_ID" precision="10" scale="0"/>
            <generator class="sequence"><param name="sequence">RECORDS_SEQ</param></generator>
        </id>
        ...
        <set name="images" inverse="true" cascade="all">
            <key column="IMG_REC_ID"/>
            <one-to-many class="com.wts.service.model.Image"/>
        </set>
    </class>
</hibernate-mapping>

图像类映射:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.wts.service.model.Image" table="IMAGES">
        <id name="imageId" type="long">
            <column name="IMG_ID" precision="10" scale="0"/>
            <generator class="sequence"><param name="sequence">IMAGES_SEQ</param></generator>
        </id>
        <many-to-one name="record" column="IMG_REC_ID" not-null="true"/>
    </class>
</hibernate-mapping>

当我在记录上调用 session.save() 时,出现以下错误:

 java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("IMAGES"."IMG_REC_ID")

我关注了bidirectional one-to-many hibernate association guide和许多不同的变体,但我永远无法让 Hibernate 将 Record 的主键插入到 Image 的外键列中!这是一个非常简单的关联(也是常见的用例),所以我必须在这里做一些偏离的事情。有人知道我在这里做错了什么吗?

编辑:

我也尝试将 key 设置为非空,但得到了相同的错误:

<set name="images" inverse="true" cascade="all">
        <key column="IMG_REC_ID" not-null="true"/>
        <one-to-many class="com.wts.service.model.Image"/>
    </set>

另外,作为旁注,当我没有设置 inverse="true"时,我可以让它工作。以下代码有效(记录和图像保存到数据库中),但图像对象无法设置多对一关联:

<set name="images" inverse="false" cascade="all">
        <key column="IMG_REC_ID" not-null="true"/>
        <one-to-many class="com.wts.service.model.Image"/>
    </set>

编辑2:

这是我调用 session.save() 的代码。图像已与记录关联,并通过 REST Web 服务 POST 进行填充。记录和图像之前并未保留。

public void createRecord(Record record) {
        //set the create bys for the images and actions
        record.setCreateDt(new Date());

        for (Image image : record.getImages()) {
            image.setCreateBy(record.getCreateBy());
            image.setCreateDt(record.getCreateDt());
        }
        for (Action action : record.getActions()) {
            action.setCreateBy(record.getCreateBy());
            action.setCreateDt(record.getCreateDt());
        }
        session.save(record);
    }

以下是在 session.commit() 之后运行的 sql 语句:

14:43:06,586 INFO  [stdout] (http--0.0.0.0-8080-1) Hibernate: select RECORDS_SEQ.nextval from dual
14:43:06,715 INFO  [stdout] (http--0.0.0.0-8080-1) Hibernate: select IMAGES_SEQ.nextval from dual
14:43:06,847 INFO  [stdout] (http--0.0.0.0-8080-1) Hibernate: insert into RECORDS (REC_EXT_ID, REC_GRP_ID, REC_APPL, REC_LATITUDE, REC_LONGITUDE, REC_PRIVATE, REC_LOCKED, REC_CREATE_BY, REC_CREATE_DT, REC_UPDATE_BY, REC_UPDATE_DT, REC_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
14:43:06,969 INFO  [stdout] (http--0.0.0.0-8080-1) Hibernate: insert into IMAGES (IMG_REC_ID, IMG_STATUS, IMG_CT_CD, IMG_FORMAT, IMG_WIDTH, IMG_HEIGHT, IMG_IMAGE, IMG_CREATE_BY, IMG_CREATE_DT, IMG_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
14:43:08,090 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--0.0.0.0-8080-1) SQL Error: 1400, SQLState: 23000
14:43:08,090 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--0.0.0.0-8080-1) ORA-01400: cannot insert NULL into ("FOSUSER"."IMAGES"."IMG_REC_ID")

最佳答案

看起来您已经将图像实体添加到记录的图像集合中,并且没有为此图像实体设置记录。像这样:

Image img = new Image();
Record rec = new Record();
rec.getImages().add(img);
// img.setRecord(rec);    Looks like this is missing in your code
session.save();

在这种情况下,在图像实体持久化过程中, hibernate 会尝试将 null 插入到不可为 null 的字段中。

更新。

请为多对一元素添加 class 属性。并删除 not-null="true":

<many-to-one name="record" column="IMG_REC_ID" class="Record"/>

关于java - 使用 Oracle 在 Hibernate 中插入多对一行时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23813076/

相关文章:

java - 如何将 Excel 单元格中的数字字符串读取为字符串(不是数字)?

java - android中固定日期和时间的警报管理器

oracle - ORA-12154 : TNS:could not resolve the connect identifier specified

sql - 甲骨文 : select maximum value from different columns of the same row

java - 在集群环境中跨 JSP 应用程序共享 HashMap

java - com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException : Unknown column 'day0_.calendar_id' in 'field list'

java - 如何从两个现有的类文字构造参数化类文字?

java - 从 Android 浏览器获取网站标题?

java - 了解 Hibernate 部分刷新行为

java - 表不是由 Hibernate 创建的