More complete "temp table" coverage and allow Dialects to influence which strategy is used
Description
Attachments
Activity
Steve Ebersole April 22, 2015 at 2:10 AM
Here are the things we need from "temp table support":
The ability to export needed persistent and global-temp-table definitions to the database (
MultiTableBulkIdStrategy#prepare
currently).The (configurable) ability to cleanup exported persistent and global-temp-table definitions from the database (
MultiTableBulkIdStrategy#release
currently).The ability to export local-temp-tables "on demand"
The ability to clean up local-temp-tables after use if indicated by env.
The ability to execute inserts into the bulk-id table
The ability to use the bulk-id table in subselects
The first 4 all relate to managing the bulk-id table definitions. The last 2 relate to using the bulk-id table to perform the multi-table update/delete. The last 2 have a variation such that the persistent table case needs to manage a "session identifier" column whereas the local-temp-table and global-temp-table cases do not.
When we need to create/drop (manage) the bulk-id table definitions depends on the strategy in use. For persistent and global-temp strategies, this happens around the SessionFactory starting and stopping. For the local-temp strategy, this happens as we need the bulk-id tables (for each session). The part I struggle with is that in the one case (persistent and global-temp strategies) we can use the DDL immediately and not have to keep it around; in the second (local-temp strategy) we do. And the fact that this leaks outside of the strategy. One possible solution there is to have the local-temp strategy itself keep track of the necessary DDL per-entity rather than the persisters having to conditionally store it or not (leakage).
Dove-tailing into that, I think it also does not make sense for PersistentClass#prepareTemporaryTables
to store its work on PersistentClass itself. I think a signature change is in order there to have that method return the Table
. We can then pass those (singly or all-together) to the strategy for export and pass the name to the persisters for it to know.
I'd like to follow a similar pattern for the last 2 goals as well. The strategy ought to be the thing that drives the generation of the bulk-id table insert statement, the generation of the bulk-id table subselect and any binding of parameters (session identifier).
Steve Ebersole April 17, 2015 at 9:24 PM
Per our IRC discussion, org.hibernate.hql.spi.MultiTableBulkIdHelper#needsIdTable
is the bit used to limit the "temp tables" that actually get created.
Steve Ebersole April 17, 2015 at 9:22 PM
Minor correction.. actually I do not allow nulls to be returned, but I do limit the "fallback choices" to what they were previously. Only the OracleDialects this behavior so far.
Steve Ebersole April 17, 2015 at 9:07 PM
Initially I decided to allow Dialects return null from #getDefaultMultiTableBulkIdStrategy
. In such cases, the behavior is the same as what used to happen. I did this because knowing how each Dialect needs to handled a fully-contained MultiTableBulkIdStrategy more of an audit than I wanted to put into this as on a late Friday afternoon
Long term, I think the best approach is to remove the Dialect method intended to support table tabled in a piecemeal fashion and to make MultiTableBulkIdStrategy be a fully self-contained contract. That requires some planning though since the calls into the Dialect methods happen from many "levels" (while building PersistentClasses, while building EntityPersisters and finally from Sessions). Anyway the Dialect methods in question are:
supportsTemporaryTables
generateTemporaryTableName
getCreateTemporaryTableString
getDropTemporaryTableString
performTemporaryTableDDLInIsolation
dropTemporaryTableAfterUse
Steve Ebersole April 17, 2015 at 7:29 PM
This is not a bug. We can argue semantics all day, but at worst it is an improvement..
Details
Details
Assignee
Reporter

On each DML/bulk update/delete for an entity in a multi-table inheritance hierarchy, an "ORA-00955: name is already used by an existing object" exception is recorded in the database error logs.
The exception is silently discarded by Hibernate, but the unnecessary failed creation and exception processing impacts performance where high volumes of bulk operations occur. Also, it creates significant data in the database server side logs.