Java Hibernate和Oracle的批插入不会记录导致ConstraintViolationException的实体
如何从Hibernate/Oracle的错误消息中确定批量插入实体时哪个实体导致了问题 安装程序Hibernate或Oracle是否有办法记录此信息Java Hibernate和Oracle的批插入不会记录导致ConstraintViolationException的实体,java,oracle,hibernate,Java,Oracle,Hibernate,如何从Hibernate/Oracle的错误消息中确定批量插入实体时哪个实体导致了问题 安装程序Hibernate或Oracle是否有办法记录此信息 Caused by: org.hibernate.exception.ConstraintViolationException: could not execute batch at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLS
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute batch
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:129)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:124)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:122)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.doExecuteBatch(BatchingBatch.java:101)
at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.execute(AbstractBatchImpl.java:161)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:207)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:390)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:303)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:349)
at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:67)
at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1166)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1223)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:268)
... 375 more
Caused by: java.sql.BatchUpdateException: ORA-00001: unique constraint (FHIR.SYS_C0022940074) violated
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:11190)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:244)
at org.jboss.jca.adapters.jdbc.WrappedStatement.executeBatch(WrappedStatement.java:1077)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:113)
... 386 more
假设我们拥有以下JPA实体:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
private Long id;
private String title;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
关于这个实体,需要注意的最重要的一点是,必须手动分配实体标识符
现在,让我们模拟一个批处理,该批处理始终会引发ConstraintViolationException
:
Session session = entityManager.unwrap(Session.class);
session.doWork(connection -> {
try (PreparedStatement st = connection.prepareStatement(
"INSERT INTO post (id, title) " +
"VALUES (?, ?)")) {
for (long i = 0; i < 5; i++) {
st.setLong(1, i % 2);
st.setString(2, String.format("High-Performance Java Persistence, Part %d", i));
st.addBatch();
}
st.executeBatch();
} catch (BatchUpdateException e) {
LOGGER.info("Batch has managed to process {} entries", e.getUpdateCounts().length);
}
});
因此,要回答这个问题,您需要使用该方法了解您成功处理了多少项,因此下一项就是导致失败的项。约束显示在异常中。要找到它,请参考以下问题:@mohit问题不是找到导致问题的约束,而是找出触发约束的实体
c.v.b.h.h.b.BatchExceptionTest - testInsertPosts
n.t.d.l.SLF4JQueryLoggingListener - Name:DATA_SOURCE_PROXY, Time:0,
Success:False,
Type:Prepared,
Batch:True,
QuerySize:1,
BatchSize:5,
Query:[
"INSERT INTO post (id, title) VALUES (?, ?)"],
Params:[
(0, High-Performance Java Persistence, Part 0),
(1, High-Performance Java Persistence, Part 1),
(0, High-Performance Java Persistence, Part 2),
(1, High-Performance Java Persistence, Part 3),
(0, High-Performance Java Persistence, Part 4)
]
c.v.b.h.h.b.BatchExceptionTest - Batch has managed to process 2 entries