gpt4 book ai didi

java - Hibernate 多表批量操作总是尝试创建临时表

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:44:01 24 4
gpt4 key购买 nike

我有一些使用连接继承的实体,我正在对它们进行批量操作。如 Multi-table Bulk Operations 中所述Hibernate 使用临时表来执行批量操作。

据我所知,临时表中的数据是临时的(在事务或 session 结束时删除),但表本身是永久性的。我看到的是 Hibernate 每次执行这样的查询时都会尝试创建临时表。在我的例子中,每小时上升超过 35.000 次。 create table 语句显然每次都失败,因为同名的表已经存在。这真的是不必要的,可能会损害性能,而且 DBA 也不高兴......

有没有办法让 Hibernate 记住它已经创建了临时表?

如果没有,是否有任何解决方法?我唯一的想法是使用单表继承来避免完全使用临时表。

Hibernate版本是4.2.8,DB是Oracle 11g。

最佳答案

我认为这是 TemporaryTableBulkIdStrategy 中的错误,因为在使用 Oracle8iDialect 时说不应删除临时表:

@Override
public boolean dropTemporaryTableAfterUse() {
return false;
}

但是这个检查只在删除表的时候进行:

protected void releaseTempTable(Queryable persister, SessionImplementor session) {
if ( session.getFactory().getDialect().dropTemporaryTableAfterUse() ) {
TemporaryTableDropWork work = new TemporaryTableDropWork( persister, session );
if ( shouldIsolateTemporaryTableDDL( session ) ) {
session.getTransactionCoordinator()
.getTransaction()
.createIsolationDelegate()
.delegateWork( work, shouldTransactIsolatedTemporaryTableDDL( session ) );
}
else {
final Connection connection = session.getTransactionCoordinator()
.getJdbcCoordinator()
.getLogicalConnection()
.getConnection();
work.execute( connection );
session.getTransactionCoordinator()
.getJdbcCoordinator()
.afterStatementExecution();
}
}
else {
// at the very least cleanup the data :)
PreparedStatement ps = null;
try {
final String sql = "delete from " + persister.getTemporaryIdTableName();
ps = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
}
catch( Throwable t ) {
log.unableToCleanupTemporaryIdTable(t);
}
finally {
if ( ps != null ) {
try {
session.getTransactionCoordinator().getJdbcCoordinator().release( ps );
}
catch( Throwable ignore ) {
// ignore
}
}
}
}
}

但现在在创建表时:

protected void createTempTable(Queryable persister, SessionImplementor session) {
// Don't really know all the codes required to adequately decipher returned jdbc exceptions here.
// simply allow the failure to be eaten and the subsequent insert-selects/deletes should fail
TemporaryTableCreationWork work = new TemporaryTableCreationWork( persister );
if ( shouldIsolateTemporaryTableDDL( session ) ) {
session.getTransactionCoordinator()
.getTransaction()
.createIsolationDelegate()
.delegateWork( work, shouldTransactIsolatedTemporaryTableDDL( session ) );
}
else {
final Connection connection = session.getTransactionCoordinator()
.getJdbcCoordinator()
.getLogicalConnection()
.getConnection();
work.execute( connection );
session.getTransactionCoordinator()
.getJdbcCoordinator()
.afterStatementExecution();
}
}

作为解决方法,您可以扩展 Oracle 方言并覆盖 dropTemporaryTableAfterUse 方法以返回 false

我填写了HHH-9744问题。

关于java - Hibernate 多表批量操作总是尝试创建临时表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29801330/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com