/
SharedSessionContractImplementor.java
534 lines (463 loc) · 17.1 KB
/
SharedSessionContractImplementor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.engine.spi;
import java.io.Serializable;
import java.sql.Connection;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import javax.persistence.FlushModeType;
import javax.persistence.TransactionRequiredException;
import javax.persistence.criteria.Selection;
import org.hibernate.CacheMode;
import org.hibernate.Criteria;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.ScrollMode;
import org.hibernate.SharedSessionContract;
import org.hibernate.Transaction;
import org.hibernate.cache.spi.CacheTransactionSynchronization;
import org.hibernate.cfg.Environment;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jpa.spi.HibernateEntityManagerImplementor;
import org.hibernate.loader.custom.CustomQuery;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.spi.QueryProducerImplementor;
import org.hibernate.query.spi.ScrollableResultsImplementor;
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder.Options;
import org.hibernate.type.descriptor.WrapperOptions;
/**
* Defines the internal contract shared between {@link org.hibernate.Session} and
* {@link org.hibernate.StatelessSession} as used by other parts of Hibernate (such as
* {@link org.hibernate.type.Type}, {@link EntityPersister} and
* {@link org.hibernate.persister.collection.CollectionPersister} implementors
*
* A Session, through this interface and SharedSessionContractImplementor, implements:<ul>
* <li>
* {@link org.hibernate.resource.jdbc.spi.JdbcSessionOwner} to drive the behavior of a "JDBC session".
* Can therefor be used to construct a JdbcCoordinator, which (for now) models a "JDBC session"
* </li>
* <li>
* {@link Options}
* to drive the creation of the {@link TransactionCoordinator} delegate.
* This allows it to be passed along to
* {@link org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder#buildTransactionCoordinator}
* </li>
* <li>
* {@link org.hibernate.engine.jdbc.LobCreationContext} to act as the context for JDBC LOB instance creation
* </li>
* <li>
* {@link org.hibernate.type.descriptor.WrapperOptions} to fulfill the behavior needed while
* binding/extracting values to/from JDBC as part of the Type contracts
* </li>
* </ul>
*
* @author Gavin King
* @author Steve Ebersole
*/
public interface SharedSessionContractImplementor
extends SharedSessionContract, JdbcSessionOwner, Options, LobCreationContext, WrapperOptions, QueryProducerImplementor {
// todo : this is the shared contract between Session and StatelessSession, but it defines methods that StatelessSession does not implement
// (it just throws UnsupportedOperationException). To me it seems like it is better to properly isolate those methods
// into just the Session hierarchy. They include (at least):
// 1) get/set CacheMode
// 2) get/set FlushMode
// 3) get/set (default) read-only
// 4) #setAutoClear
// 5) #disableTransactionAutoJoin
/**
* Get the creating <tt>SessionFactoryImplementor</tt>
*/
SessionFactoryImplementor getFactory();
SessionEventListenerManager getEventListenerManager();
/**
* Get the persistence context for this session.
* See also {@link #getPersistenceContextInternal()} for
* an alternative.
*
* This method is not extremely fast: if you need to access
* the PersistenceContext multiple times, prefer keeping
* a reference to it over invoking this method multiple times.
*/
PersistenceContext getPersistenceContext();
JdbcCoordinator getJdbcCoordinator();
JdbcServices getJdbcServices();
/**
* The multi-tenancy tenant identifier, if one.
*
* @return The tenant identifier; may be {@code null}
*/
String getTenantIdentifier();
/**
* A UUID associated with each Session. Useful mainly for logging.
*
* @return The UUID
*/
UUID getSessionIdentifier();
/**
* Checks whether the session is closed. Provided separately from
* {@link #isOpen()} as this method does not attempt any JTA synchronization
* registration, where as {@link #isOpen()} does; which makes this one
* nicer to use for most internal purposes.
*
* @return {@code true} if the session is closed; {@code false} otherwise.
*/
boolean isClosed();
/**
* Checks whether the session is open or is waiting for auto-close
*
* @return {@code true} if the session is closed or if it's waiting for auto-close; {@code false} otherwise.
*/
default boolean isOpenOrWaitingForAutoClose() {
return !isClosed();
}
/**
* Performs a check whether the Session is open, and if not:<ul>
* <li>marks current transaction (if one) for rollback only</li>
* <li>throws an IllegalStateException (JPA defines the exception type)</li>
* </ul>
*/
default void checkOpen() {
checkOpen( true );
}
/**
* Performs a check whether the Session is open, and if not:<ul>
* <li>if {@code markForRollbackIfClosed} is true, marks current transaction (if one) for rollback only</li>
* <li>throws an IllegalStateException (JPA defines the exception type)</li>
* </ul>
*/
void checkOpen(boolean markForRollbackIfClosed);
/**
* Marks current transaction (if one) for rollback only
*/
void markForRollbackOnly();
/**
* A "timestamp" at or before the start of the current transaction.
*
* @apiNote This "timestamp" need not be related to timestamp in the Java Date/millisecond
* sense. It just needs to be an incrementing value. See
* {@link CacheTransactionSynchronization#getCurrentTransactionStartTimestamp()}
*/
long getTransactionStartTimestamp();
/**
* @deprecated (since 5.3) Use {@link #getTransactionStartTimestamp()} instead.
*/
@Deprecated
default long getTimestamp() {
return getTransactionStartTimestamp();
}
/**
* The current CacheTransactionContext associated with the Session. This may
* return {@code null} when the Session is not currently part of a transaction.
*/
CacheTransactionSynchronization getCacheTransactionSynchronization();
/**
* Does this <tt>Session</tt> have an active Hibernate transaction
* or is there a JTA transaction in progress?
*/
boolean isTransactionInProgress();
/**
* Check if an active Transaction is necessary for the update operation to be executed.
* If an active Transaction is necessary but it is not then a TransactionRequiredException is raised.
*
* @param exceptionMessage, the message to use for the TransactionRequiredException
*/
default void checkTransactionNeededForUpdateOperation(String exceptionMessage) {
if ( !isTransactionInProgress() ) {
throw new TransactionRequiredException( exceptionMessage );
}
}
/**
* Provides access to the underlying transaction or creates a new transaction if
* one does not already exist or is active. This is primarily for internal or
* integrator use.
*
* @return the transaction
*/
Transaction accessTransaction();
/**
* Hide the changing requirements of entity key creation
*
* @param id The entity id
* @param persister The entity persister
*
* @return The entity key
*/
EntityKey generateEntityKey(Serializable id, EntityPersister persister);
/**
* Retrieves the interceptor currently in use by this event source.
*
* @return The interceptor.
*/
Interceptor getInterceptor();
/**
* Enable/disable automatic cache clearing from after transaction
* completion (for EJB3)
*/
void setAutoClear(boolean enabled);
/**
* Initialize the collection (if not already initialized)
*/
void initializeCollection(PersistentCollection collection, boolean writing)
throws HibernateException;
/**
* Load an instance without checking if it was deleted.
* <p/>
* When <tt>nullable</tt> is disabled this method may create a new proxy or
* return an existing proxy; if it does not exist, throw an exception.
* <p/>
* When <tt>nullable</tt> is enabled, the method does not create new proxies
* (but might return an existing proxy); if it does not exist, return
* <tt>null</tt>.
* <p/>
* When <tt>eager</tt> is enabled, the object is eagerly fetched
*/
Object internalLoad(String entityName, Serializable id, boolean eager, boolean nullable)
throws HibernateException;
default Object internalLoad(
String entityName,
Serializable id,
boolean eager,
boolean nullable,
Boolean unwrapProxy) throws HibernateException {
return internalLoad( entityName, id, eager, nullable );
}
/**
* Load an instance immediately. This method is only called when lazily initializing a proxy.
* Do not return the proxy.
*/
Object immediateLoad(String entityName, Serializable id) throws HibernateException;
/**
* Execute a <tt>find()</tt> query
*/
List list(String query, QueryParameters queryParameters) throws HibernateException;
/**
* Execute an <tt>iterate()</tt> query
*/
Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException;
/**
* Execute a <tt>scroll()</tt> query
*/
ScrollableResultsImplementor scroll(String query, QueryParameters queryParameters) throws HibernateException;
/**
* Execute a criteria query
*/
ScrollableResultsImplementor scroll(Criteria criteria, ScrollMode scrollMode);
/**
* Execute a criteria query
*/
List list(Criteria criteria);
/**
* Execute a filter
*/
List listFilter(Object collection, String filter, QueryParameters queryParameters) throws HibernateException;
/**
* Iterate a filter
*/
Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters)
throws HibernateException;
/**
* Get the <tt>EntityPersister</tt> for any instance
*
* @param entityName optional entity name
* @param object the entity instance
*/
EntityPersister getEntityPersister(String entityName, Object object) throws HibernateException;
/**
* Get the entity instance associated with the given <tt>Key</tt>,
* calling the Interceptor if necessary
*/
Object getEntityUsingInterceptor(EntityKey key) throws HibernateException;
/**
* Return the identifier of the persistent object, or null if
* not associated with the session
*/
Serializable getContextEntityIdentifier(Object object);
/**
* The best guess entity name for an entity not in an association
*/
String bestGuessEntityName(Object object);
/**
* The guessed entity name for an entity not in an association
*/
String guessEntityName(Object entity) throws HibernateException;
/**
* Instantiate the entity class, initializing with the given identifier
*/
Object instantiate(String entityName, Serializable id) throws HibernateException;
/**
* Execute an SQL Query
*/
List listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters)
throws HibernateException;
/**
* Execute an SQL Query
*/
ScrollableResultsImplementor scrollCustomQuery(CustomQuery customQuery, QueryParameters queryParameters)
throws HibernateException;
/**
* Execute a native SQL query, and return the results as a fully built list.
*
* @param spec The specification of the native SQL query to execute.
* @param queryParameters The parameters by which to perform the execution.
*
* @return The result list.
*
* @throws HibernateException
*/
List list(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
throws HibernateException;
/**
* Execute a native SQL query, and return the results as a scrollable result.
*
* @param spec The specification of the native SQL query to execute.
* @param queryParameters The parameters by which to perform the execution.
*
* @return The resulting scrollable result.
*
* @throws HibernateException
*/
ScrollableResultsImplementor scroll(NativeSQLQuerySpecification spec, QueryParameters queryParameters);
int getDontFlushFromFind();
/**
* Execute a HQL update or delete query
*/
int executeUpdate(String query, QueryParameters queryParameters) throws HibernateException;
/**
* Execute a native SQL update or delete query
*/
int executeNativeUpdate(NativeSQLQuerySpecification specification, QueryParameters queryParameters)
throws HibernateException;
CacheMode getCacheMode();
void setCacheMode(CacheMode cm);
/**
* Set the flush mode for this session.
* <p/>
* The flush mode determines the points at which the session is flushed.
* <i>Flushing</i> is the process of synchronizing the underlying persistent
* store with persistable state held in memory.
* <p/>
* For a logically "read only" session, it is reasonable to set the session's
* flush mode to {@link FlushMode#MANUAL} at the start of the session (in
* order to achieve some extra performance).
*
* @param flushMode the new flush mode
*
* @deprecated (since 5.2) use {@link #setHibernateFlushMode(FlushMode)} instead
*/
@Deprecated
void setFlushMode(FlushMode flushMode);
/**
* Get the flush mode for this session.
* <p/>
* For users of the Hibernate native APIs, we've had to rename this method
* as defined by Hibernate historically because the JPA contract defines a method of the same
* name, but returning the JPA {@link FlushModeType} rather than Hibernate's {@link FlushMode}. For
* the former behavior, use {@link #getHibernateFlushMode()} instead.
*
* @return The FlushModeType in effect for this Session.
*/
FlushModeType getFlushMode();
/**
* Set the flush mode for this session.
* <p/>
* The flush mode determines the points at which the session is flushed.
* <i>Flushing</i> is the process of synchronizing the underlying persistent
* store with persistable state held in memory.
* <p/>
* For a logically "read only" session, it is reasonable to set the session's
* flush mode to {@link FlushMode#MANUAL} at the start of the session (in
* order to achieve some extra performance).
*
* @param flushMode the new flush mode
*/
void setHibernateFlushMode(FlushMode flushMode);
/**
* Get the current flush mode for this session.
*
* @return The flush mode
*/
FlushMode getHibernateFlushMode();
Connection connection();
void flush();
boolean isEventSource();
void afterScrollOperation();
boolean shouldAutoClose();
boolean isAutoCloseSessionEnabled();
default boolean isQueryParametersValidationEnabled(){
return getFactory().getSessionFactoryOptions().isQueryParametersValidationEnabled();
}
/**
* Get the load query influencers associated with this session.
*
* @return the load query influencers associated with this session;
* should never be null.
*/
LoadQueryInfluencers getLoadQueryInfluencers();
/**
* The converter associated to a Session might be lazily initialized: only invoke
* this getter when there is actual need to use it.
*
* @return the ExceptionConverter for this Session.
*/
ExceptionConverter getExceptionConverter();
/**
* Get the currently configured JDBC batch size either at the Session-level or SessionFactory-level.
*
* If the Session-level JDBC batch size was not configured, return the SessionFactory-level one.
*
* @return Session-level or or SessionFactory-level JDBC batch size.
*
* @since 5.2
*
* @see org.hibernate.boot.spi.SessionFactoryOptions#getJdbcBatchSize
* @see org.hibernate.boot.SessionFactoryBuilder#applyJdbcBatchSize
*/
default Integer getConfiguredJdbcBatchSize() {
final Integer sessionJdbcBatchSize = getJdbcBatchSize();
return sessionJdbcBatchSize == null ?
ConfigurationHelper.getInt(
Environment.STATEMENT_BATCH_SIZE,
getFactory().getProperties(),
1
) :
sessionJdbcBatchSize;
}
/**
* @deprecated (since 5.2) - see deprecation note on
* org.hibernate.jpa.spi.HibernateEntityManagerImplementor#createQuery(java.lang.String, java.lang.Class, javax.persistence.criteria.Selection, org.hibernate.jpa.spi.HibernateEntityManagerImplementor.QueryOptions)
* @return The typed query
*/
@Deprecated
<T> QueryImplementor<T> createQuery(
String jpaqlString,
Class<T> resultClass,
Selection selection,
HibernateEntityManagerImplementor.QueryOptions queryOptions);
/**
* This is similar to {@link #getPersistenceContext()}, with
* two main differences:
* a) this version performs better as
* it allows for inlining and probably better prediction
* b) see SessionImpl{@link #getPersistenceContext()} : it
* does some checks on the current state of the Session.
*
* Choose wisely: performance is important, correctness comes first.
*
* @return the PersistenceContext associated to this session.
*/
PersistenceContext getPersistenceContextInternal();
}