下面列出了怎么用org.hibernate.engine.spi.SharedSessionContractImplementor的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public final boolean setCurrentSession(SharedSessionContractImplementor session) throws HibernateException {
if ( session == this.session ) {
return false;
}
else {
if ( this.session != null ) {
final String msg = generateUnexpectedSessionStateMessage( session );
if ( isConnectedToSession() ) {
throw new HibernateException(
"Illegal attempt to associate a collection with two open sessions. " + msg
);
}
else {
LOG.logUnexpectedSessionInCollectionNotConnected( msg );
this.session = session;
return true;
}
}
else {
this.session = session;
return true;
}
}
}
@Override
public NClob mergeNClob(NClob original, NClob target, SharedSessionContractImplementor session) {
if ( original != target ) {
try {
// the NCLOB just read during the load phase of merge
final OutputStream connectedStream = target.setAsciiStream( 1L );
// the NCLOB from the detached state
final InputStream detachedStream = original.getAsciiStream();
StreamCopier.copy( detachedStream, connectedStream );
return target;
}
catch (SQLException e ) {
throw session.getFactory().getSQLExceptionHelper().convert( e, "unable to merge NCLOB data" );
}
}
else {
return NEW_LOCATOR_LOB_MERGE_STRATEGY.mergeNClob( original, target, session );
}
}
public void createTempTable(
IdTableInfoImpl idTableInfo,
TempTableDdlTransactionHandling ddlTransactionHandling,
SharedSessionContractImplementor 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( idTableInfo, session.getFactory() );
if ( ddlTransactionHandling == TempTableDdlTransactionHandling.NONE ) {
final Connection connection = session.getJdbcCoordinator()
.getLogicalConnection()
.getPhysicalConnection();
work.execute( connection );
session.getJdbcCoordinator().afterStatementExecution();
}
else {
session.getTransactionCoordinator()
.createIsolationDelegate()
.delegateWork( work, ddlTransactionHandling == TempTableDdlTransactionHandling.ISOLATE_AND_TRANSACT );
}
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names,
SharedSessionContractImplementor session, Object owner)
throws HibernateException, SQLException
{
String name = rs.getString(names[0]);
if (rs.wasNull()) {
return null;
}
for (PersistentEnum value : returnedClass().getEnumConstants()) {
if (name.equals(value.getId())) {
return value;
}
}
throw new IllegalStateException(
"Unknown " + returnedClass().getSimpleName() + " value [" + name + "]");
}
@Override
public void setIdentifier(Object entity, Serializable id, EntityMode entityMode, SharedSessionContractImplementor session) {
final Object[] extractedValues = mappedIdentifierType.getPropertyValues( id, entityMode );
final Object[] injectionValues = new Object[extractedValues.length];
final PersistenceContext persistenceContext = session.getPersistenceContext();
for ( int i = 0; i < virtualIdComponent.getSubtypes().length; i++ ) {
final Type virtualPropertyType = virtualIdComponent.getSubtypes()[i];
final Type idClassPropertyType = mappedIdentifierType.getSubtypes()[i];
if ( virtualPropertyType.isEntityType() && !idClassPropertyType.isEntityType() ) {
if ( session == null ) {
throw new AssertionError(
"Deprecated version of getIdentifier (no session) was used but session was required"
);
}
final String associatedEntityName = ( (EntityType) virtualPropertyType ).getAssociatedEntityName();
final EntityKey entityKey = session.generateEntityKey(
(Serializable) extractedValues[i],
sessionFactory.getMetamodel().entityPersister( associatedEntityName )
);
// it is conceivable there is a proxy, so check that first
Object association = persistenceContext.getProxy( entityKey );
if ( association == null ) {
// otherwise look for an initialized version
association = persistenceContext.getEntity( entityKey );
if ( association == null ) {
// get the association out of the entity itself
association = sessionFactory.getMetamodel().entityPersister( entityName ).getPropertyValue(
entity,
virtualIdComponent.getPropertyNames()[i]
);
}
}
injectionValues[i] = association;
}
else {
injectionValues[i] = extractedValues[i];
}
}
virtualIdComponent.setPropertyValues( entity, injectionValues, entityMode );
}
private void handleNaturalIdReattachment(Object entity, SharedSessionContractImplementor session) {
if ( !hasNaturalIdentifier() ) {
return;
}
if ( getEntityMetamodel().hasImmutableNaturalId() ) {
// we assume there were no changes to natural id during detachment for now, that is validated later
// during flush.
return;
}
final NaturalIdHelper naturalIdHelper = session.getPersistenceContext().getNaturalIdHelper();
final Serializable id = getIdentifier( entity, session );
// for reattachment of mutable natural-ids, we absolutely positively have to grab the snapshot from the
// database, because we have no other way to know if the state changed while detached.
final Object[] naturalIdSnapshot;
final Object[] entitySnapshot = session.getPersistenceContext().getDatabaseSnapshot( id, this );
if ( entitySnapshot == StatefulPersistenceContext.NO_ROW ) {
naturalIdSnapshot = null;
}
else {
naturalIdSnapshot = naturalIdHelper.extractNaturalIdValues( entitySnapshot, this );
}
naturalIdHelper.removeSharedNaturalIdCrossReference( this, id, naturalIdSnapshot );
naturalIdHelper.manageLocalNaturalIdCrossReference(
this,
id,
naturalIdHelper.extractNaturalIdValues( entity, this ),
naturalIdSnapshot,
CachedNaturalIdValueSource.UPDATE
);
}
/**
* Register the "hydrated" state of an entity instance, after the first step of 2-phase loading.
*
* Add the "hydrated state" (an array) of an uninitialized entity to the session. We don't try
* to resolve any associations yet, because there might be other entities waiting to be
* read from the JDBC result set we are currently processing
*
* @param persister The persister for the hydrated entity
* @param id The entity identifier
* @param values The entity values
* @param rowId The rowId for the entity
* @param object An optional instance for the entity being loaded
* @param lockMode The lock mode
* @param session The Session
*/
public static void postHydrate(
final EntityPersister persister,
final Serializable id,
final Object[] values,
final Object rowId,
final Object object,
final LockMode lockMode,
final SharedSessionContractImplementor session) {
final Object version = Versioning.getVersion( values, persister );
session.getPersistenceContext().addEntry(
object,
Status.LOADING,
values,
rowId,
id,
version,
lockMode,
true,
persister,
false
);
if ( version != null && LOG.isTraceEnabled() ) {
final String versionStr = persister.isVersioned()
? persister.getVersionType().toLoggableString( version, session.getFactory() )
: "null";
LOG.tracef( "Version: %s", versionStr );
}
}
/**
* Execute an SQL query and attempt to instantiate instances of the class mapped by the given
* persister from each row of the <tt>ResultSet</tt>. If an object is supplied, will attempt to
* initialize that object. If a collection is supplied, attempt to initialize that collection.
*/
public List doQueryAndInitializeNonLazyCollections(
final SharedSessionContractImplementor session,
final QueryParameters queryParameters,
final boolean returnProxies) throws HibernateException, SQLException {
return doQueryAndInitializeNonLazyCollections(
session,
queryParameters,
returnProxies,
null
);
}
@Override
public int execute(QueryParameters parameters, SharedSessionContractImplementor session) throws HibernateException {
for (String delete : deletes) {
doExecute( parameters, session, delete, parameterSpecifications );
}
// finally, execute the original sql statement
return super.execute( parameters, session );
}
/**
* Called by wrappers that batch initialize collections
*/
public final void loadCollectionBatch(
final SharedSessionContractImplementor session,
final Serializable[] ids,
final Type type) throws HibernateException {
if ( LOG.isDebugEnabled() ) {
LOG.debugf(
"Batch loading collection: %s",
MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() )
);
}
Type[] idTypes = new Type[ids.length];
Arrays.fill( idTypes, type );
try {
doQueryAndInitializeNonLazyCollections(
session,
new QueryParameters( idTypes, ids, ids ),
true
);
}
catch (SQLException sqle) {
throw factory.getJdbcServices().getSqlExceptionHelper().convert(
sqle,
"could not initialize a collection batch: " +
MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ),
getSQLString()
);
}
LOG.debug( "Done batch load" );
}
@Override
public void nullSafeSet(
PreparedStatement st,
Object value,
int begin,
boolean[] settable,
SharedSessionContractImplementor session)
throws HibernateException, SQLException {
Object[] subvalues = nullSafeGetValues( value, entityMode );
int loc = 0;
for ( int i = 0; i < propertySpan; i++ ) {
int len = propertyTypes[i].getColumnSpan( session.getFactory() );
//noinspection StatementWithEmptyBody
if ( len == 0 ) {
//noop
}
else if ( len == 1 ) {
if ( settable[loc] ) {
propertyTypes[i].nullSafeSet( st, subvalues[i], begin, session );
begin++;
}
}
else {
boolean[] subsettable = new boolean[len];
System.arraycopy( settable, loc, subsettable, 0, len );
propertyTypes[i].nullSafeSet( st, subvalues[i], begin, subsettable, session );
begin += ArrayHelper.countTrue( subsettable );
}
loc += len;
}
}
@Override
public int execute(QueryParameters parameters, SharedSessionContractImplementor session) throws HibernateException {
BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, deleteHandler.getTargetedQueryable() );
if ( session.isEventSource() ) {
( (EventSource) session ).getActionQueue().addAction( action );
}
else {
action.getAfterTransactionCompletionProcess().doAfterTransactionCompletion( true, session );
}
return deleteHandler.execute( session, parameters );
}
@Override
public Object readIndex(ResultSet rs, String[] aliases, SharedSessionContractImplementor session)
throws HibernateException, SQLException {
Object index = getIndexType().nullSafeGet( rs, aliases, session, null );
if ( index == null ) {
throw new HibernateException( "null index column for collection: " + navigableRole.getFullPath() );
}
index = decrementIndexByBase( index );
return index;
}
@Override
public int bind(
PreparedStatement statement,
QueryParameters qp,
SharedSessionContractImplementor session,
int start) throws SQLException {
final int columnSpan = definedParameterType.getColumnSpan( session.getFactory() );
final String fullParamName = filterName + '.' + parameterName;
final Object value = session.getLoadQueryInfluencers().getFilterParameterValue(fullParamName);
final Type type = session.getLoadQueryInfluencers().getFilterParameterType(fullParamName);
if ( Collection.class.isInstance( value ) ) {
int positions = 0;
Iterator itr = ( ( Collection ) value ).iterator();
while ( itr.hasNext() ) {
Object next = itr.next();
qp.bindDynamicParameter( type, next );
definedParameterType.nullSafeSet( statement, next, start + positions, session );
positions += columnSpan;
}
return positions;
}
else {
qp.bindDynamicParameter(type, value);
definedParameterType.nullSafeSet( statement, value, start, session );
return columnSpan;
}
}
@Override
public Object nullSafeGet( ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner ) throws HibernateException, SQLException
{
final Object result = rs.getObject( names[0] );
if ( !rs.wasNull() )
{
String content = null;
if ( result instanceof String )
{
content = (String) result;
}
else if ( result instanceof PGobject )
{
content = ((PGobject) result).getValue();
}
// Other types currently ignored
if ( content != null )
{
return content.toString();
}
}
return null;
}
public static Object[] toParameterArray(
QueryParameters queryParameters,
List<ParameterSpecification> parameterSpecifications,
SharedSessionContractImplementor session) {
return PreparedStatementAdaptor.bind( adaptor -> {
int pos = 1;
for (ParameterSpecification parameterSpecification: parameterSpecifications) {
pos += parameterSpecification.bind(adaptor, queryParameters, session, pos);
}
} );
}
private CollectionInitializer getSubselectInitializer(Serializable key, SharedSessionContractImplementor session) {
if ( !isSubselectLoadable() ) {
return null;
}
final PersistenceContext persistenceContext = session.getPersistenceContext();
SubselectFetch subselect = persistenceContext.getBatchFetchQueue()
.getSubselect( session.generateEntityKey( key, getOwnerEntityPersister() ) );
if ( subselect == null ) {
return null;
}
else {
// Take care of any entities that might have
// been evicted!
Iterator iter = subselect.getResult().iterator();
while ( iter.hasNext() ) {
if ( !persistenceContext.containsEntity( (EntityKey) iter.next() ) ) {
iter.remove();
}
}
// Run a subquery loader
return createSubselectInitializer( subselect, session );
}
}
public void nullSafeSet(
PreparedStatement st, Object value, int index,
SharedSessionContractImplementor session
) throws HibernateException, SQLException {
MonetaryAmount ma = (MonetaryAmount) value;
BigDecimal amt = ma == null ? null : ma.getAmount();
Currency cur = ma == null ? null : ma.getCurrency();
StandardBasicTypes.BIG_DECIMAL.nullSafeSet( st, amt, index, session );
StandardBasicTypes.CURRENCY.nullSafeSet( st, cur, index + 1, session );
}
@Override
public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) throws CacheException {
final EntityPersister persister = getPersister();
if ( persister.canWriteToCache() ) {
final EntityDataAccess cache = persister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(
getId(),
persister,
session.getFactory(),
session.getTenantIdentifier()
);
if ( success &&
cacheEntry != null &&
!persister.isCacheInvalidationRequired() &&
session.getCacheMode().isPutEnabled() ) {
final boolean put = cacheAfterUpdate( cache, ck );
if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
session.getFactory().getStatistics().entityCachePut(
StatsHelper.INSTANCE.getRootEntityRole( persister ),
getPersister().getCacheAccessStrategy().getRegion().getName()
);
}
}
else {
cache.unlockItem(session, ck, lock );
}
}
postCommitUpdate( success );
}
@Override
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int i, SharedSessionContractImplementor sessionImplementor) throws HibernateException, SQLException {
LineSegment line = (LineSegment) value;
if (value == null) {
preparedStatement.setNull(i, java.sql.Types.OTHER);
} else {
preparedStatement.setObject(i, new PGlseg(line.getP1().getX(), line.getP1().getY(),
line.getP2().getX(), line.getP2().getY()));
}
}
/**
* Update a persistent instance
*/
void update(
Serializable id,
Object[] fields,
int[] dirtyFields,
boolean hasDirtyCollection,
Object[] oldFields,
Object oldVersion,
Object object,
Object rowId,
SharedSessionContractImplementor session
) throws HibernateException;
@Override
public void update(
Serializable id,
Object[] fields,
int[] dirtyFields,
boolean hasDirtyCollection,
Object[] oldFields,
Object oldVersion,
Object object,
Object rowId,
SharedSessionContractImplementor session) throws HibernateException {
throw new UnsupportedOperationException( "Wrong method calls. Use the reactive equivalent." );
}
@Override
public Object assemble(Serializable cached, SharedSessionContractImplementor session, Object owner)
throws HibernateException {
if ( cached==null ) {
return null;
}
else {
return deepCopy( cached, session.getFactory() );
}
}
/**
* Is this instance persistent or detached?
* <p/>
* If <tt>assumed</tt> is non-null, don't hit the database to make the determination, instead assume that
* value; the client code must be prepared to "recover" in the case that this assumed result is incorrect.
*
* @param entityName The name of the entity
* @param entity The entity instance
* @param assumed The assumed return value, if avoiding database hit is desired
* @param session The session
*
* @return {@code true} if the given entity is not transient (meaning it is either detached/persistent)
*/
@SuppressWarnings("SimplifiableIfStatement")
public static boolean isNotTransient(String entityName, Object entity, Boolean assumed, SharedSessionContractImplementor session) {
if ( entity instanceof HibernateProxy ) {
return true;
}
if ( session.getPersistenceContext().isEntryFor( entity ) ) {
return true;
}
// todo : shouldnt assumed be revered here?
return !isTransient( entityName, entity, assumed, session );
}
public Object instantiate(Object parent, SharedSessionContractImplementor session)
throws HibernateException {
Object result = instantiate( entityMode );
if ( componentTuplizer.hasParentProperty() && parent != null ) {
componentTuplizer.setParent(
result,
session.getPersistenceContext().proxyFor( parent ),
session.getFactory()
);
}
return result;
}
@Override
public void nullSafeSet(
CallableStatement statement, Object value, String name, SharedSessionContractImplementor session) throws SQLException {
if ( canDoSetting() ) {
((ProcedureParameterNamedBinder) getUserType() ).nullSafeSet( statement, value, name, session );
}
else {
throw new UnsupportedOperationException(
"Type [" + getUserType() + "] does support parameter binding by name"
);
}
}
@Override
protected PreparedStatement prepare(String insertSQL, SharedSessionContractImplementor session) throws SQLException {
return session
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( insertSQL, keyColumns );
}
private void handlePotentiallyEmptyCollectionRootReturns(
LoadPlan loadPlan,
Serializable[] collectionKeys,
ResultSet resultSet,
SharedSessionContractImplementor session) {
if ( collectionKeys == null ) {
// this is not a collection initializer (and empty collections will be detected by looking for
// the owner's identifier in the result set)
return;
}
// this is a collection initializer, so we must create a collection
// for each of the passed-in keys, to account for the possibility
// that the collection is empty and has no rows in the result set
//
// todo : move this inside CollectionReturn ?
CollectionPersister persister = ( (CollectionReturn) loadPlan.getReturns().get( 0 ) ).getCollectionPersister();
for ( Serializable key : collectionKeys ) {
if ( LOG.isDebugEnabled() ) {
LOG.debugf(
"Preparing collection intializer : %s",
MessageHelper.collectionInfoString( persister, key, session.getFactory() )
);
}
session.getPersistenceContext()
.getLoadContexts()
.getCollectionLoadContext( resultSet )
.getLoadingCollection( persister, key );
}
}
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
throws HibernateException, SQLException {
BigDecimal amt = StandardBasicTypes.BIG_DECIMAL.nullSafeGet( rs, names[0], session);
Currency cur = StandardBasicTypes.CURRENCY.nullSafeGet( rs, names[1], session );
if ( amt == null ) return null;
return new MonetaryAmount( amt, cur );
}
protected SqlStatementWrapper executeQueryStatement(
String sqlStatement,
QueryParameters queryParameters,
boolean scroll,
List<AfterLoadAction> afterLoadActions,
SharedSessionContractImplementor session) throws SQLException {
// Processing query filters.
queryParameters.processFilters( sqlStatement, session );
// Applying LIMIT clause.
final LimitHandler limitHandler = getLimitHandler(
queryParameters.getRowSelection()
);
String sql = limitHandler.processSql( queryParameters.getFilteredSQL(), queryParameters.getRowSelection() );
// Adding locks and comments.
sql = session.getJdbcServices().getJdbcEnvironment().getDialect()
.addSqlHintOrComment(
sql,
queryParameters,
session.getFactory().getSessionFactoryOptions().isCommentsEnabled()
);
final PreparedStatement st = prepareQueryStatement( sql, queryParameters, limitHandler, scroll, session );
return new SqlStatementWrapper( st, getResultSet( st, queryParameters.getRowSelection(), limitHandler, queryParameters.hasAutoDiscoverScalarTypes(), session ) );
}