optiona=false导致的问题之Hibernate源码分析
2021-04-21 16:26
标签:erro execution null com private upd etc error 过程 8月初,帮助同事接手了一个hibernate实体保存出错的问题。解决过程比较有意思,最终还是需要分析hibnate源码来解决,现记录如下: 实体类定义如下: @Entity @Proxy(lazy=true) @DiscriminatorValue("1") @SecondaryTable(name="act_order", pkJoinColumns=@primaryKeyJoinColumn(name="order_id")) @Table(appliesTo="act_order",fetch=FetchMode.SELECT) public class ActOrder extends Order{ @Column(name="txt",table="act_order") private String text; ... } @Table(appliesTo="order") public class Order { @id(name="order_id") private String orderId; ... } 1 背景: 子表act_order 通过主键order_id关联 基表order 表主键order_id,一对一的关联,但order的记录有可能是找不到一条对应的act_order. 本次操作是修改act_order 子表的txt值从null -> ‘aaa‘。 库表里面已经存在一条数据: 2 日志: Hibernate: insert into SUB_ORDER(TXT, ORDER_ID) values (?, ?) 根据日志是主键冲突导致插入失败,看到这条日志会感觉很奇怪,本应update语句为何变成了insert? org.hibernate.persister.entity.AbstractEntityPersister: 程序会判断act_order库表是一个NullableTable (默认optional=true),该条记录的所有旧值(除了primary key)是null,所以isRowToUpdate=false的错误结论。 3 初步的解决方案如下,参考红色字体: @Table(appliesTo="act_order",fetch=FetchMode.SELECT,optional=false) public class ActOrder extends Order 这样的话即便txt字段为null或者空串"",都会生成一条记录到act_order 库表。order有一条记录,则act_order也会对应生成一条记录。 本以为问题轻松解决,但第二天就遭到打脸。新数据创建没有任何问题,历史数据有可能一条order找不到对应act_order记录.因为一旦 设置为optional=false,hibernate就会认为一条order记录一定会对应一条act_order.如果查找不到,系统就会抛出异常。 4 最终解决方案是。 optiona=false导致的问题之Hibernate源码分析 标签:erro execution null com private upd etc error 过程 原文地址:https://www.cnblogs.com/pmh905001/p/12245096.html
09 Aug 2019 06:21:36,590 -ERROR insert into SUB_ORDER (TXT, ORDER_ID) values (‘aaa‘, 51598892) com.reserveamerica.framework.persistence.toplinkimpl.BaseOraclePooledConnector$2.sqlException(BaseOraclePooledConnector.java:442)
java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (LIVE_TX.PK_ACT_ORDER) violated
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:943)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1150)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:4875)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1361)
at sun.reflect.GeneratedMethodAccessor99.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at oracle.ucp.jdbc.proxy.StatementProxyFactory.invoke(StatementProxyFactory.java:353)
at oracle.ucp.jdbc.proxy.PreparedStatementProxyFactory.invoke(PreparedStatementProxyFactory.java:178)
at com.sun.proxy.$Proxy78.executeUpdate(Unknown Source)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2421)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2485)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2805)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:114)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:180)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
上一篇:.net core 常见设计模式-IChangeToken
下一篇:js高级一
文章标题:optiona=false导致的问题之Hibernate源码分析
文章链接:http://soscw.com/index.php/essay/77676.html