More complete "temp table" coverage and allow Dialects to influence which strategy is used

Description

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.

Attachments

1

Activity

Show:

Steve Ebersole April 22, 2015 at 2:10 AM

Here are the things we need from "temp table support":

  1. The ability to export needed persistent and global-temp-table definitions to the database (MultiTableBulkIdStrategy#prepare currently).

  2. The (configurable) ability to cleanup exported persistent and global-temp-table definitions from the database (MultiTableBulkIdStrategy#release currently).

  3. The ability to export local-temp-tables "on demand"

  4. The ability to clean up local-temp-tables after use if indicated by env.

  5. The ability to execute inserts into the bulk-id table

  6. 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:

  1. supportsTemporaryTables

  2. generateTemporaryTableName

  3. getCreateTemporaryTableString

  4. getDropTemporaryTableString

  5. performTemporaryTableDDLInIsolation

  6. 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..

Fixed

Details

Assignee

Reporter

Time tracking

20.93h logged

Components

Fix versions

Priority

Created April 14, 2015 at 8:00 PM
Updated February 23, 2016 at 3:06 PM
Resolved April 23, 2015 at 8:21 PM