36
36
import org .jboss .logging .Logger ;
37
37
38
38
import org .hibernate .HibernateException ;
39
+ import org .hibernate .JDBCException ;
39
40
import org .hibernate .cfg .AvailableSettings ;
40
41
import org .hibernate .cfg .Mappings ;
41
- import org .hibernate .dialect .Dialect ;
42
42
import org .hibernate .engine .jdbc .spi .JdbcConnectionAccess ;
43
+ import org .hibernate .engine .jdbc .spi .JdbcServices ;
43
44
import org .hibernate .engine .spi .Mapping ;
44
45
import org .hibernate .engine .spi .SessionFactoryImplementor ;
45
46
import org .hibernate .engine .spi .SessionImplementor ;
46
47
import org .hibernate .hql .internal .ast .HqlSqlWalker ;
47
48
import org .hibernate .internal .AbstractSessionImpl ;
49
+ import org .hibernate .internal .CoreMessageLogger ;
48
50
import org .hibernate .internal .util .config .ConfigurationHelper ;
49
51
import org .hibernate .mapping .Column ;
50
52
import org .hibernate .mapping .PersistentClass ;
51
53
import org .hibernate .mapping .Table ;
52
54
import org .hibernate .persister .entity .Queryable ;
55
+ import org .hibernate .sql .SelectValues ;
53
56
import org .hibernate .type .UUIDCharType ;
54
57
55
58
/**
56
59
* @author Steve Ebersole
57
60
*/
58
61
public class PersistentTableBulkIdStrategy implements MultiTableBulkIdStrategy {
59
- private static final Logger log = Logger .getLogger ( PersistentTableBulkIdStrategy .class );
62
+ private static final CoreMessageLogger log = Logger .getMessageLogger (
63
+ CoreMessageLogger .class ,
64
+ PersistentTableBulkIdStrategy .class .getName ()
65
+ );
60
66
61
67
public static final String CLEAN_UP_ID_TABLES = "hibernate.hql.bulk_id_strategy.persistent.clean_up" ;
62
68
public static final String SCHEMA = "hibernate.hql.bulk_id_strategy.persistent.schema" ;
@@ -69,7 +75,7 @@ public class PersistentTableBulkIdStrategy implements MultiTableBulkIdStrategy {
69
75
70
76
@ Override
71
77
public void prepare (
72
- Dialect dialect ,
78
+ JdbcServices jdbcServices ,
73
79
JdbcConnectionAccess connectionAccess ,
74
80
Mappings mappings ,
75
81
Mapping mapping ,
@@ -93,7 +99,7 @@ public void prepare(
93
99
final Table idTableDefinition = generateIdTableDefinition ( entityMapping );
94
100
idTableDefinitions .add ( idTableDefinition );
95
101
}
96
- exportTableDefinitions ( idTableDefinitions , dialect , connectionAccess , mappings , mapping );
102
+ exportTableDefinitions ( idTableDefinitions , jdbcServices , connectionAccess , mappings , mapping );
97
103
}
98
104
99
105
protected Table generateIdTableDefinition (PersistentClass entityMapping ) {
@@ -104,7 +110,7 @@ protected Table generateIdTableDefinition(PersistentClass entityMapping) {
104
110
if ( schema != null ) {
105
111
idTable .setSchema ( schema );
106
112
}
107
- Iterator itr = entityMapping .getIdentityTable ().getPrimaryKey ().getColumnIterator ();
113
+ Iterator itr = entityMapping .getTable ().getPrimaryKey ().getColumnIterator ();
108
114
while ( itr .hasNext () ) {
109
115
Column column = (Column ) itr .next ();
110
116
idTable .addColumn ( column .clone () );
@@ -120,12 +126,20 @@ protected Table generateIdTableDefinition(PersistentClass entityMapping) {
120
126
121
127
protected void exportTableDefinitions (
122
128
List <Table > idTableDefinitions ,
123
- Dialect dialect ,
129
+ JdbcServices jdbcServices ,
124
130
JdbcConnectionAccess connectionAccess ,
125
131
Mappings mappings ,
126
132
Mapping mapping ) {
127
133
try {
128
- Connection connection = connectionAccess .obtainConnection ();
134
+ Connection connection ;
135
+ try {
136
+ connection = connectionAccess .obtainConnection ();
137
+ }
138
+ catch (UnsupportedOperationException e ) {
139
+ // assume this comes from org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl
140
+ log .debug ( "Unable to obtain JDBC connection; assuming ID tables already exist or wont be needed" );
141
+ return ;
142
+ }
129
143
130
144
try {
131
145
Statement statement = connection .createStatement ();
@@ -135,10 +149,12 @@ protected void exportTableDefinitions(
135
149
if ( tableCleanUpDdl == null ) {
136
150
tableCleanUpDdl = new ArrayList <String >();
137
151
}
138
- tableCleanUpDdl .add ( idTableDefinition .sqlDropString ( dialect , null , null ) );
152
+ tableCleanUpDdl .add ( idTableDefinition .sqlDropString ( jdbcServices . getDialect () , null , null ) );
139
153
}
140
154
try {
141
- statement .execute ( idTableDefinition .sqlCreateString ( dialect , mapping , null , null ) );
155
+ final String sql = idTableDefinition .sqlCreateString ( jdbcServices .getDialect (), mapping , null , null );
156
+ jdbcServices .getSqlStatementLogger ().logStatement ( sql );
157
+ statement .execute ( sql );
142
158
}
143
159
catch (SQLException e ) {
144
160
log .debugf ( "Error attempting to export id-table [%s] : %s" , idTableDefinition .getName (), e .getMessage () );
@@ -162,8 +178,8 @@ protected void exportTableDefinitions(
162
178
}
163
179
164
180
@ Override
165
- public void release (Dialect dialect , JdbcConnectionAccess connectionAccess ) {
166
- if ( ! cleanUpTables ) {
181
+ public void release (JdbcServices jdbcServices , JdbcConnectionAccess connectionAccess ) {
182
+ if ( ! cleanUpTables || tableCleanUpDdl == null ) {
167
183
return ;
168
184
}
169
185
@@ -175,6 +191,7 @@ public void release(Dialect dialect, JdbcConnectionAccess connectionAccess) {
175
191
176
192
for ( String cleanupDdl : tableCleanUpDdl ) {
177
193
try {
194
+ jdbcServices .getSqlStatementLogger ().logStatement ( cleanupDdl );
178
195
statement .execute ( cleanupDdl );
179
196
}
180
197
catch (SQLException e ) {
@@ -202,8 +219,8 @@ public void release(Dialect dialect, JdbcConnectionAccess connectionAccess) {
202
219
public UpdateHandler buildUpdateHandler (SessionFactoryImplementor factory , HqlSqlWalker walker ) {
203
220
return new TableBasedUpdateHandlerImpl ( factory , walker ) {
204
221
@ Override
205
- protected String extraIdSelectValues ( ) {
206
- return "cast(? as char)" ;
222
+ protected void addAnyExtraIdSelectValues ( SelectValues selectClause ) {
223
+ selectClause . addParameter ( Types . CHAR , 36 ) ;
207
224
}
208
225
209
226
@ Override
@@ -213,32 +230,65 @@ protected String generateIdSubselect(Queryable persister) {
213
230
214
231
@ Override
215
232
protected int handlePrependedParametersOnIdSelection (PreparedStatement ps , SessionImplementor session , int pos ) throws SQLException {
216
- if ( ! AbstractSessionImpl .class .isInstance ( session ) ) {
217
- throw new HibernateException ( "Only available on SessionImpl instances" );
218
- }
219
- UUIDCharType .INSTANCE .set ( ps , ( (AbstractSessionImpl ) session ).getSessionIdentifier (), pos , session );
233
+ bindSessionIdentifier ( ps , session , pos );
220
234
return 1 ;
221
235
}
222
236
223
237
@ Override
224
238
protected void handleAddedParametersOnUpdate (PreparedStatement ps , SessionImplementor session , int position ) throws SQLException {
225
- if ( ! AbstractSessionImpl .class .isInstance ( session ) ) {
226
- throw new HibernateException ( "Only available on SessionImpl instances" );
227
- }
228
- UUIDCharType .INSTANCE .set ( ps , ( (AbstractSessionImpl ) session ).getSessionIdentifier (), position , session );
239
+ bindSessionIdentifier ( ps , session , position );
240
+ }
241
+
242
+ @ Override
243
+ protected void releaseFromUse (Queryable persister , SessionImplementor session ) {
244
+ // clean up our id-table rows
245
+ cleanUpRows ( determineIdTableName ( persister ), session );
229
246
}
230
247
};
231
248
}
232
249
250
+ private void bindSessionIdentifier (PreparedStatement ps , SessionImplementor session , int position ) throws SQLException {
251
+ if ( ! AbstractSessionImpl .class .isInstance ( session ) ) {
252
+ throw new HibernateException ( "Only available on SessionImpl instances" );
253
+ }
254
+ UUIDCharType .INSTANCE .set ( ps , ( (AbstractSessionImpl ) session ).getSessionIdentifier (), position , session );
255
+ }
256
+
257
+ private void cleanUpRows (String tableName , SessionImplementor session ) {
258
+ final String sql = "delete from " + tableName + " where hib_sess_id=?" ;
259
+ try {
260
+ PreparedStatement ps = null ;
261
+ try {
262
+ ps = session .getTransactionCoordinator ().getJdbcCoordinator ().getStatementPreparer ().prepareStatement ( sql , false );
263
+ bindSessionIdentifier ( ps , session , 1 );
264
+ ps .executeUpdate ();
265
+ }
266
+ finally {
267
+ if ( ps != null ) {
268
+ try {
269
+ ps .close ();
270
+ }
271
+ catch ( Throwable ignore ) {
272
+ // ignore
273
+ }
274
+ }
275
+ }
276
+ }
277
+ catch (SQLException e ) {
278
+ throw convert ( session .getFactory (), e , "Unable to clean up id table [" + tableName + "]" , sql );
279
+ }
280
+ }
281
+
282
+ protected JDBCException convert (SessionFactoryImplementor factory , SQLException e , String message , String sql ) {
283
+ throw factory .getSQLExceptionHelper ().convert ( e , message , sql );
284
+ }
285
+
233
286
@ Override
234
287
public DeleteHandler buildDeleteHandler (SessionFactoryImplementor factory , HqlSqlWalker walker ) {
235
288
return new TableBasedDeleteHandlerImpl ( factory , walker ) {
236
289
@ Override
237
- protected String extraIdSelectValues () {
238
- final Dialect dialect = factory ().getDialect ();
239
- return dialect .requiresCastingOfParametersInSelectClause ()
240
- ? dialect .cast ( "?" , Types .CHAR , 36 )
241
- : "?" ;
290
+ protected void addAnyExtraIdSelectValues (SelectValues selectClause ) {
291
+ selectClause .addParameter ( Types .CHAR , 36 );
242
292
}
243
293
244
294
@ Override
@@ -248,19 +298,19 @@ protected String generateIdSubselect(Queryable persister) {
248
298
249
299
@ Override
250
300
protected int handlePrependedParametersOnIdSelection (PreparedStatement ps , SessionImplementor session , int pos ) throws SQLException {
251
- if ( ! AbstractSessionImpl .class .isInstance ( session ) ) {
252
- throw new HibernateException ( "Only available on SessionImpl instances" );
253
- }
254
- UUIDCharType .INSTANCE .set ( ps , ( (AbstractSessionImpl ) session ).getSessionIdentifier (), pos , session );
301
+ bindSessionIdentifier ( ps , session , pos );
255
302
return 1 ;
256
303
}
257
304
258
305
@ Override
259
306
protected void handleAddedParametersOnDelete (PreparedStatement ps , SessionImplementor session ) throws SQLException {
260
- if ( ! AbstractSessionImpl .class .isInstance ( session ) ) {
261
- throw new HibernateException ( "Only available on SessionImpl instances" );
262
- }
263
- UUIDCharType .INSTANCE .set ( ps , ( (AbstractSessionImpl ) session ).getSessionIdentifier (), 1 , session );
307
+ bindSessionIdentifier ( ps , session , 1 );
308
+ }
309
+
310
+ @ Override
311
+ protected void releaseFromUse (Queryable persister , SessionImplementor session ) {
312
+ // clean up our id-table rows
313
+ cleanUpRows ( determineIdTableName ( persister ), session );
264
314
}
265
315
};
266
316
}
0 commit comments