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

记一次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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值