attempted to assign id from null one-to-one property [com.xxx.xxx]

本文记录了在Oracle数据库升级至19c版本,并保持Hibernate版本不变的情况下,进行兼容性验证时遇到的问题及解决方案。主要讨论了在transaction.commit()时出现的错误,分析了代码debug过程及数据库数据缺失导致的异常,最后提供了修正方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记一次troubleshooting

Background:
Oracle升级到19c,保持原有的Hibernate版本不变验证可用性。所以讲测试环境Oracle数据导出,在本地环境安装Oracle 19c导入数据,debug验证。

Issue:
启动报错在transaction.commit();的代码时:
attempted to assign id from null one-to-one property [com.xxx.xxx]
网上查了很多都是save的时候报错,和我的情况不一样。

		Transaction transaction = null;
        try {
            transaction = getSession().beginTransaction();
            String queryString = "from CCxxx as model where model.isActive = true";
            Query queryObject = getSession().createQuery(queryString);
            queryObject.setCacheRegion(CCXX_CACHE_REGION);
            queryObject.setCacheable(true);
            List<Currency> ccyList = queryObject.list();
            transaction.commit();
            return ccyList;
        } catch (RuntimeException re) {
             transaction.rollback();
             throw re;
        } finally {
            close();
        }

Debug代码时发现在org.hibernate.event.def.AbstractSaveEventListenergetEntityState()函数的入参entity为一个所有变量值都为null的一个POJO。

protected int getEntityState(Object entity, String entityName, EntityEntry entry, SessionImplementor source) {
        if (entry != null) {
            if (entry.getStatus() != Status.DELETED) {
                if (log.isTraceEnabled()) {
                    log.trace("persistent instance of: " + this.getLoggableName(entityName, entity));
                }

                return 0;
            } else {
                if (log.isTraceEnabled()) {
                    log.trace("deleted instance of: " + this.getLoggableName(entityName, entity));
                }

                return 3;
            }
        } else if (ForeignKeys.isTransient(entityName, entity, this.getAssumedUnsaved(), source)) {
            if (log.isTraceEnabled()) {
                log.trace("transient instance of: " + this.getLoggableName(entityName, entity));
            }

            return 1;
        } else {
            if (log.isTraceEnabled()) {
                log.trace("detached instance of: " + this.getLoggableName(entityName, entity));
            }

            return 2;
        }
    }

导致判断匹配了ForeignKeys.isTransient(entityName, entity, this.getAssumedUnsaved(), source)return 1
最终在org.hibernate.id.ForeignGeneratorgenerate(SessionImplementor sessionImplementor, Object object)函数中抛出IdentifierGenerationException

public Serializable generate(SessionImplementor sessionImplementor, Object object) {
        Session session = (Session)sessionImplementor;
        EntityPersister persister = sessionImplementor.getFactory().getEntityPersister(this.entityName);
        Object associatedObject = persister.getPropertyValue(object, this.propertyName, session.getEntityMode());
        if (associatedObject == null) {
            throw new IdentifierGenerationException("attempted to assign id from null one-to-one property [" + this.getRole() + "]");
        } else {
            Type propertyType = persister.getPropertyType(this.propertyName);
            EntityType foreignValueSourceType;
            if (propertyType.isEntityType()) {
                foreignValueSourceType = (EntityType)propertyType;
            } else {
                foreignValueSourceType = (EntityType)persister.getPropertyType("_identifierMapper." + this.propertyName);
            }

            Serializable id;
            try {
                id = ForeignKeys.getEntityIdentifierIfNotUnsaved(foreignValueSourceType.getAssociatedEntityName(), associatedObject, sessionImplementor);
            } catch (TransientObjectException var10) {
                id = session.save(foreignValueSourceType.getAssociatedEntityName(), associatedObject);
            }

            return session.contains(object) ? IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR : id;
        }
}

Solution
究其原因,程序中两个Entity已经配置了<one-to-one>,所以数据必须一一对应。
检查database中的一个表中缺少了一条数据,发现是由于exp的sql中存在关键字Infinity,使得在imp的时候报错

SQL Error: ORA-00984: column not allowed here
00984. 00000 - “column not allowed here”

修正后重新imp。

### Simulink 中输入端口赋值的方法 在Simulink环境中,有多种方式可以实现对模型输入端口的有效赋值。 #### 使用对话框直接设置参数 对于某些特定类型的模块,可以通过配置模块属性来设定初始条件或常数值。例如,在对话框中指定参数的方式适用于不需要动态变化的情况[^1]。 ```matlab set_param('model_name/block_path', 'ParameterName', 'ParameterValue') ``` 此命令允许用户修改已存在模块的具体参数而不必手动打开每个单独的界面调整。 #### 添加输入端口并通过信号线传递数据 当需要引入外部源的数据流时,则应考虑采用`Inport`模块作为接口,并利用MATLAB工作区内的变量完成初始化操作。具体而言,如果目标是在整个模拟周期内保持恒定不变的单一数值,那么可以直接创建相应的工作空间条目;而对于随时间演化的函数形式(像正弦波),则需预先计算好采样点并存储于数组之中再传入仿真环境内部处理[^2]: ```matlab t = linspace(0, 10, 101)'; % 时间序列 u = sin(t); % 正弦波幅值 assignin('base', 'timeVector', t); assignin('base', 'signalData', u); ``` 上述代码片段展示了如何构建一个持续时间为10秒的标准正弦曲线样本集,并将其分配至基础工作区内供后续调用。 #### 封装系统的多端口管理策略 针对较为复杂的应用场景下可能涉及到多个独立通道的情形,合理规划各路输入的名字有助于提高整体结构清晰度以及维护便利性。按照既定规则组合而成的独特标识符能够帮助快速定位所需资源位置,同时也便于后期扩展升级过程中维持一致性[^3]: - 输入信号名称遵循“前缀+原始信号名部分字符+后缀”的模式; - 同一类别下的不同实例间共享一致性的前后附加字符串模板。 #### 解决连接兼容性问题 值得注意的是,在实际搭建电路级或其他物理域模型期间可能会遭遇因组件类型差异而导致互连失败的现象。此时应当仔细甄别所选用部件所属分类,确保它们之间具备良好的电气特性匹配关系从而顺利完成组装过程[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值