/** * Determine the id to use for updating. * * @param entity The entity. * @param persister The entity persister * @param requestedId The requested identifier * @param session The session * * @return The id. * * @throws TransientObjectException If the entity is considered transient. */ protected Serializable getUpdateId( Object entity, EntityPersister persister, Serializable requestedId, SessionImplementor session) { // use the id assigned to the instance Serializable id = persister.getIdentifier( entity, session ); if ( id == null ) { // assume this is a newly instantiated transient object // which should be saved rather than updated throw new TransientObjectException( "The given object has a null identifier: " + persister.getEntityName() ); } else { return id; } }
protected CollectionInitializer getAppropriateInitializer(Serializable key, SessionImplementor session) { if ( queryLoaderName != null ) { // if there is a user-specified loader, return that // TODO: filters!? return initializer; } CollectionInitializer subselectInitializer = getSubselectInitializer( key, session ); if ( subselectInitializer != null ) { return subselectInitializer; } else if ( session.getEnabledFilters().isEmpty() ) { return initializer; } else { return createCollectionInitializer( session.getLoadQueryInfluencers() ); } }
/** * Constructs an EntityIdentityInsertAction * * @param state The current (extracted) entity state * @param instance The entity instance * @param persister The entity persister * @param isVersionIncrementDisabled Whether version incrementing is disabled * @param session The session * @param isDelayed Are we in a situation which allows the insertion to be delayed? * * @throws HibernateException Indicates an illegal state */ public EntityIdentityInsertAction( Object[] state, Object instance, EntityPersister persister, boolean isVersionIncrementDisabled, SessionImplementor session, boolean isDelayed) { super( ( isDelayed ? generateDelayedPostInsertIdentifier() : null ), state, instance, isVersionIncrementDisabled, persister, session ); this.isDelayed = isDelayed; this.delayedEntityKey = isDelayed ? generateDelayedEntityKey() : null; }
protected boolean handleInterception(FlushEntityEvent event) { SessionImplementor session = event.getSession(); EntityEntry entry = event.getEntityEntry(); EntityPersister persister = entry.getPersister(); Object entity = event.getEntity(); //give the Interceptor a chance to modify property values final Object[] values = event.getPropertyValues(); final boolean intercepted = invokeInterceptor( session, entity, entry, values, persister ); //now we might need to recalculate the dirtyProperties array if ( intercepted && event.isDirtyCheckPossible() && !event.isDirtyCheckHandledByInterceptor() ) { int[] dirtyProperties; if ( event.hasDatabaseSnapshot() ) { dirtyProperties = persister.findModified( event.getDatabaseSnapshot(), values, entity, session ); } else { dirtyProperties = persister.findDirty( values, entry.getLoadedState(), entity, session ); } event.setDirtyProperties( dirtyProperties ); } return intercepted; }
@Override public Object load( Serializable id, Object optionalObject, SessionImplementor session, LockOptions lockOptions) { final Serializable[] batch = session.getPersistenceContext() .getBatchFetchQueue() .getEntityBatch( persister(), id, maxBatchSize, persister().getEntityMode() ); final int numberOfIds = ArrayHelper.countNonNull( batch ); if ( numberOfIds <= 1 ) { return singleKeyLoader.load( id, optionalObject, session ); } final Serializable[] idsToLoad = new Serializable[numberOfIds]; System.arraycopy( batch, 0, idsToLoad, 0, numberOfIds ); if ( log.isDebugEnabled() ) { log.debugf( "Batch loading entity: %s", MessageHelper.infoString( persister(), idsToLoad, session.getFactory() ) ); } QueryParameters qp = buildQueryParameters( id, idsToLoad, optionalObject, lockOptions ); List results = dynamicLoader.doEntityBatchFetch( session, qp, idsToLoad ); return getObjectFromList( results, id, session ); }
@Override public boolean isModified(final Object old, final Object current, final boolean[] checkable, final SessionImplementor session) throws HibernateException { if ( current == null ) { return old != null; } if ( old == null ) { return true; } Object[] oldValues = ( Object[] ) old; int loc = 0; for ( int i = 0; i < propertySpan; i++ ) { int len = propertyTypes[i].getColumnSpan( session.getFactory() ); boolean[] subcheckable = new boolean[len]; System.arraycopy( checkable, loc, subcheckable, 0, len ); if ( propertyTypes[i].isModified( oldValues[i], getPropertyValue( current, i ), subcheckable, session ) ) { return true; } loc += len; } return false; }
public Object[] buildResultRow(Object[] data, ResultSet resultSet, SessionImplementor session) throws SQLException, HibernateException { Object[] resultRow; if ( !hasScalars ) { resultRow = data; } else { // build an array with indices equal to the total number // of actual returns in the result Hibernate will return // for this query (scalars + non-scalars) resultRow = new Object[ columnProcessors.length ]; for ( int i = 0; i < columnProcessors.length; i++ ) { resultRow[i] = columnProcessors[i].extract( data, resultSet, session ); } } return resultRow; }
@Override protected void applyPostLoadLocks(Object[] row, LockMode[] lockModesArray, SessionImplementor session) { // todo : scalars??? // if ( row.length != lockModesArray.length ) { // return; // } // // for ( int i = 0; i < lockModesArray.length; i++ ) { // if ( LockMode.OPTIMISTIC_FORCE_INCREMENT.equals( lockModesArray[i] ) ) { // final EntityEntry pcEntry = // } // else if ( LockMode.PESSIMISTIC_FORCE_INCREMENT.equals( lockModesArray[i] ) ) { // // } // } }
protected boolean shouldUseFollowOnLocking( QueryParameters parameters, Dialect dialect, List<AfterLoadAction> afterLoadActions) { if ( dialect.useFollowOnLocking() ) { // currently only one lock mode is allowed in follow-on locking final LockMode lockMode = determineFollowOnLockMode( parameters.getLockOptions() ); final LockOptions lockOptions = new LockOptions( lockMode ); if ( lockOptions.getLockMode() != LockMode.UPGRADE_SKIPLOCKED ) { LOG.usingFollowOnLocking(); lockOptions.setTimeOut( parameters.getLockOptions().getTimeOut() ); lockOptions.setScope( parameters.getLockOptions().getScope() ); afterLoadActions.add( new AfterLoadAction() { @Override public void afterLoad(SessionImplementor session, Object entity, Loadable persister) { ( (Session) session ).buildLockRequest( lockOptions ).lock( persister.getEntityName(), entity ); } } ); parameters.setLockOptions( new LockOptions() ); return true; } } return false; }
private QueryPlanWork specificationToWork(Specification<T> spec, Pageable pageable) { // Unwrap to Hibernate final QueryImpl query = getQuery(spec, pageable).unwrap(QueryImpl.class); final String hql = query.getQueryString(); // Create translator final QueryTranslator queryTranslator = new ASTQueryTranslatorFactory().createQueryTranslator("", hql, Collections.emptyMap(), em.unwrap(SessionImplementor.class).getFactory(), null); queryTranslator.compile(Collections.emptyMap(), false); // Get translated query and parameters final String sql = queryTranslator.getSQLString(); final Object[] parameters = translateParameters(query, queryTranslator); // Done return new QueryPlanWork(sql, parameters); }
protected Document receiveResponse() throws IOException, DocumentException { try { SessionImplementor session = (SessionImplementor)new _RootDAO().getSession(); Connection connection = session.getJdbcConnectionAccess().obtainConnection(); String response = null; try { CallableStatement call = connection.prepareCall(iResponseSql); call.registerOutParameter(1, java.sql.Types.CLOB); call.execute(); response = call.getString(1); call.close(); } finally { session.getJdbcConnectionAccess().releaseConnection(connection); } if (response==null || response.length()==0) return null; StringReader reader = new StringReader(response); Document document = (new SAXReader()).read(reader); reader.close(); return document; } catch (Exception e) { sLog.error("Unable to receive response: "+e.getMessage(),e); return null; } finally { _RootDAO.closeCurrentThreadSessions(); } }
/** * Get the id value from the owning entity key, usually the same as the key, but might be some * other property, in the case of property-ref * * @param key The collection owner key * @param session The session from which the request is originating. * @return The collection owner's id, if it can be obtained from the key; * otherwise, null is returned */ public Serializable getIdOfOwnerOrNull(Serializable key, SessionImplementor session) { Serializable ownerId = null; if ( foreignKeyPropertyName == null ) { ownerId = key; } else { Type keyType = getPersister( session ).getKeyType(); EntityPersister ownerPersister = getPersister( session ).getOwnerEntityPersister(); // TODO: Fix this so it will work for non-POJO entity mode Class ownerMappedClass = ownerPersister.getMappedClass(); if ( ownerMappedClass.isAssignableFrom( keyType.getReturnedClass() ) && keyType.getReturnedClass().isInstance( key ) ) { // the key is the owning entity itself, so get the ID from the key ownerId = ownerPersister.getIdentifier( key, session ); } else { // TODO: check if key contains the owner ID } } return ownerId; }
protected void putResultInQueryCache( final SessionImplementor session, final QueryParameters queryParameters, final Type[] resultTypes, final QueryCache queryCache, final QueryKey key, final List result) { if ( session.getCacheMode().isPutEnabled() ) { boolean put = queryCache.put( key, key.getResultTransformer().getCachedResultTypes( resultTypes ), result, queryParameters.isNaturalKeyLookup(), session ); if ( put && factory.getStatistics().isStatisticsEnabled() ) { factory.getStatisticsImplementor() .queryCachePut( getQueryIdentifier(), queryCache.getRegion().getName() ); } } }
/** * Add an uninitialized instance of an entity class, as a placeholder to ensure object * identity. Must be called before <tt>postHydrate()</tt>. * * Create a "temporary" entry for a newly instantiated entity. The entity is uninitialized, * but we need the mapping from id to instance in order to guarantee uniqueness. * * @param key The entity key * @param object The entity instance * @param persister The entity persister * @param lockMode The lock mode * @param lazyPropertiesAreUnFetched Are lazy properties still un-fetched? * @param session The Session */ public static void addUninitializedEntity( final EntityKey key, final Object object, final EntityPersister persister, final LockMode lockMode, final boolean lazyPropertiesAreUnFetched, final SessionImplementor session) { session.getPersistenceContext().addEntity( object, Status.LOADING, null, key, null, lockMode, true, persister, false, lazyPropertiesAreUnFetched ); }
public synchronized Serializable generate(final SessionImplementor session, Object obj) { // maxLo < 1 indicates a hilo generator with no hilo :? if ( maxLo < 1 ) { //keep the behavior consistent even for boundary usages IntegralDataTypeHolder value = null; while ( value == null || value.lt( 0 ) ) { value = super.generateHolder( session ); } return value.makeValue(); } return hiloOptimizer.generate( new AccessCallback() { public IntegralDataTypeHolder getNextValue() { return generateHolder( session ); } @Override public String getTenantIdentifier() { return session.getTenantIdentifier(); } } ); }
/** * Apply the {@link Type#replace} operation across a series of values. * * @param original The source of the state * @param target The target into which to replace the source values. * @param types The value types * @param session The originating session * @param owner The entity "owning" the values * @param copyCache A map representing a cache of already replaced state * * @return The replaced state */ public static Object[] replace( final Object[] original, final Object[] target, final Type[] types, final SessionImplementor session, final Object owner, final Map copyCache) { Object[] copied = new Object[original.length]; for ( int i = 0; i < types.length; i++ ) { if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || original[i] == BackrefPropertyAccessor.UNKNOWN ) { copied[i] = target[i]; } else { copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache ); } } return copied; }
@SuppressWarnings({ "unchecked" }) public Object replace( Object original, Object target, SessionImplementor session, Object owner, Map copyCache, ForeignKeyDirection foreignKeyDirection) { return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT == foreignKeyDirection ? getReplacement( (T) original, (T) target, session ) : target; }
@Override public int getSize(Serializable key, SessionImplementor session) { try { PreparedStatement st = session.getTransactionCoordinator() .getJdbcCoordinator() .getStatementPreparer() .prepareStatement( sqlSelectSizeString ); try { getKeyType().nullSafeSet( st, key, 1, session ); ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); try { return rs.next() ? rs.getInt( 1 ) - baseIndex : 0; } finally { session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st ); } } finally { session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } catch ( SQLException sqle ) { throw getSQLExceptionHelper().convert( sqle, "could not retrieve collection size: " + MessageHelper.collectionInfoString( this, key, getFactory() ), sqlSelectSizeString ); } }
private CollectionInitializer getSubselectInitializer(Serializable key, SessionImplementor 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 ); } }
@Override public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException { //we must use the "remembered" uk value, since it is //not available from the EntityEntry during assembly if (cached==null) { return null; } else { final Serializable key = (Serializable) getPersister(session) .getKeyType() .assemble( cached, session, owner); return resolveKey( key, session, owner ); } }
/** * Perform an up-to-date check for the given set of query spaces. * * * @param spaces The spaces to check * @param timestamp The timestamp against which to check. * * @param session * @return Whether all those spaces are up-to-date * * @throws CacheException Indicated problem delegating to underlying region. */ public boolean isUpToDate(Set<Serializable> spaces, Long timestamp, SessionImplementor session) throws CacheException { final boolean stats = factory != null && factory.getStatistics().isStatisticsEnabled(); for ( Serializable space : spaces ) { final Long lastUpdate = getLastUpdateTimestampForSpace( space, session ); if ( lastUpdate == null ) { if ( stats ) { factory.getStatisticsImplementor().updateTimestampsCacheMiss(); } //the last update timestamp was lost from the cache //(or there were no updates since startup!) //updateTimestamps.put( space, new Long( updateTimestamps.nextTimestamp() ) ); //result = false; // safer } else { if ( DEBUG_ENABLED ) { LOG.debugf( "[%s] last update timestamp: %s", space, lastUpdate + ", result set timestamp: " + timestamp ); } if ( stats ) { factory.getStatisticsImplementor().updateTimestampsCacheHit(); } if ( lastUpdate >= timestamp ) { return false; } } } return true; }
public Object replace( Object original, Object target, SessionImplementor session, Object owner, Map copyCache) throws HibernateException { return userType.replace(original, target, session, owner); }
/** * Generate an info message string relating to a particular managed * collection. Attempts to intelligently handle property-refs issues * where the collection key is not the same as the owner key. * * @param persister The persister for the collection * @param collection The collection itself * @param collectionKey The collection key * @param session The session * @return An info string, in the form [Foo.bars#1] */ public static String collectionInfoString( CollectionPersister persister, PersistentCollection collection, Serializable collectionKey, SessionImplementor session ) { StringBuilder s = new StringBuilder(); s.append( '[' ); if ( persister == null ) { s.append( "<unreferenced>" ); } else { s.append( persister.getRole() ); s.append( '#' ); Type ownerIdentifierType = persister.getOwnerEntityPersister() .getIdentifierType(); Serializable ownerKey; // TODO: Is it redundant to attempt to use the collectionKey, // or is always using the owner id sufficient? if ( collectionKey.getClass().isAssignableFrom( ownerIdentifierType.getReturnedClass() ) ) { ownerKey = collectionKey; } else { ownerKey = session.getPersistenceContext() .getEntry( collection.getOwner() ).getId(); } s.append( ownerIdentifierType.toLoggableString( ownerKey, session.getFactory() ) ); } s.append( ']' ); return s.toString(); }
@Override public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) throws HibernateException { if ( session == null ) { return BackrefPropertyAccessor.UNKNOWN; } else { return session.getPersistenceContext().getIndexInOwner( entityName, propertyName, target, mergeMap ); } }
public void nullSafeSet( PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) throws HibernateException, SQLException { getIdentifierOrUniqueKeyType( session.getFactory() ) .nullSafeSet( st, getIdentifier( value, session ), index, settable, session ); }
@Override protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { Object[] resultRow = getResultRow( row, rs, session ); return ( holderClass == null && resultRow.length == 1 ? resultRow[ 0 ] : resultRow ); }
@Override public Object load(Serializable id, Object optionalObject, SessionImplementor session, LockOptions lockOptions) { final Serializable[] batch = session.getPersistenceContext() .getBatchFetchQueue() .getEntityBatch( persister(), id, batchSizes[0], persister().getEntityMode() ); final int numberOfIds = ArrayHelper.countNonNull( batch ); if ( numberOfIds <= 1 ) { return ( (UniqueEntityLoader) loaders[batchSizes.length-1] ).load( id, optionalObject, session ); } // Uses the first batch-size bigger than the number of actual ids in the batch int indexToUse = batchSizes.length-1; for ( int i = 0; i < batchSizes.length-1; i++ ) { if ( batchSizes[i] >= numberOfIds ) { indexToUse = i; } else { break; } } final Serializable[] idsToLoad = new Serializable[ batchSizes[indexToUse] ]; System.arraycopy( batch, 0, idsToLoad, 0, numberOfIds ); for ( int i = numberOfIds; i < batchSizes[indexToUse]; i++ ) { idsToLoad[i] = id; } return doBatchLoad( id, loaders[indexToUse], session, idsToLoad, optionalObject, lockOptions ); }
private static int bindNamedParameters( final PreparedStatement ps, final Map namedParams, final int start, final NamedParameterSource source, final SessionImplementor session) throws SQLException, HibernateException { if ( namedParams != null ) { final boolean debugEnabled = LOG.isDebugEnabled(); // assumes that types are all of span 1 final Iterator iter = namedParams.entrySet().iterator(); int result = 0; while ( iter.hasNext() ) { final Map.Entry e = (Map.Entry) iter.next(); final String name = (String) e.getKey(); final TypedValue typedVal = (TypedValue) e.getValue(); final int[] locations = source.getNamedParameterLocations( name ); for ( int location : locations ) { if ( debugEnabled ) { LOG.debugf( "bindNamedParameters() %s -> %s [%s]", typedVal.getValue(), name, location + start ); } typedVal.getType().nullSafeSet( ps, typedVal.getValue(), location + start, session ); } result += locations.length; } return result; } return 0; }
@Override public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { return resolveAny( (String) discriminatorType.nullSafeGet( rs, names[0], session, owner ), (Serializable) identifierType.nullSafeGet( rs, names[1], session, owner ), session ); }
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) throws StaleObjectStateException, JDBCException { if ( getLockMode().greaterThan( LockMode.READ ) ) { LOG.hsqldbSupportsOnlyReadCommittedIsolation(); } super.lock( id, version, object, timeout, session ); }
public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session) throws HibernateException { final Serializable id = session.getContextEntityIdentifier( entity ); final EntityEntry entry = session.getPersistenceContext().getEntry( entity ); if ( entry == null ) { throw new HibernateException( "entity is not associated with the session: " + id ); } if ( LOG.isTraceEnabled() ) { LOG.tracev( "Initializing lazy properties of: {0}, field access: {1}", MessageHelper.infoString( this, id, getFactory() ), fieldName ); } if ( session.getCacheMode().isGetEnabled() && hasCache() ) { final CacheKey cacheKey = session.generateCacheKey( id, getIdentifierType(), getEntityName() ); final Object ce = CacheHelper.fromSharedCache( session, cacheKey, getCacheAccessStrategy() ); if ( ce != null ) { final CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory); if ( !cacheEntry.areLazyPropertiesUnfetched() ) { //note early exit here: return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry ); } } } return initializeLazyPropertiesFromDatastore( fieldName, entity, session, id, entry ); }
@Override protected String applyLocks( String sql, QueryParameters parameters, Dialect dialect, List<AfterLoadAction> afterLoadActions) throws QueryException { final LockOptions lockOptions = parameters.getLockOptions(); if ( lockOptions == null || ( lockOptions.getLockMode() == LockMode.NONE && lockOptions.getAliasLockCount() == 0 ) ) { return sql; } // user is request locking, lets see if we can apply locking directly to the SQL... // some dialects wont allow locking with paging... afterLoadActions.add( new AfterLoadAction() { private final LockOptions originalLockOptions = lockOptions.makeCopy(); @Override public void afterLoad(SessionImplementor session, Object entity, Loadable persister) { ( (Session) session ).buildLockRequest( originalLockOptions ).lock( persister.getEntityName(), entity ); } } ); parameters.getLockOptions().setLockMode( LockMode.READ ); return sql; }
protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) { if ( !Hibernate.isInitialized(object) ) { throw new PersistentObjectException("uninitialized proxy passed to save()"); } else { return false; } }
/** * Constructs a PersistentElementHolder * * @param session The session * @param element The DOM element */ @SuppressWarnings("UnusedDeclaration") public PersistentElementHolder(SessionImplementor session, Element element) { super( session ); this.element = element; setInitialized(); }
@Override public Object replace( final Object original, final Object target, final SessionImplementor session, final Object owner, final Map copyCache) throws HibernateException { if ( original == null ) { return null; } if ( !Hibernate.isInitialized( original ) ) { return target; } // for a null target, or a target which is the same as the original, we // need to put the merged elements in a new collection Object result = target == null || target == original ? instantiateResult( original ) : target; //for arrays, replaceElements() may return a different reference, since //the array length might not match result = replaceElements( original, result, owner, copyCache, session ); if ( original == target ) { // get the elements back into the target making sure to handle dirty flag boolean wasClean = PersistentCollection.class.isInstance( target ) && !( ( PersistentCollection ) target ).isDirty(); //TODO: this is a little inefficient, don't need to do a whole // deep replaceElements() call replaceElements( result, target, owner, copyCache, session ); if ( wasClean ) { ( ( PersistentCollection ) target ).clearDirty(); } result = target; } return result; }
@Override public final Object nullSafeGet( ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { return resolve( hydrate(rs, names, session, owner), session, owner ); }
@Override public void initialize(Serializable id, SessionImplementor session) throws HibernateException { loadCollectionSubselect( session, keys, values, types, namedParameters, getKeyType() ); }
/** * Constructs a PersistentList. * * @param session The session * @param list The raw list */ public PersistentList(SessionImplementor session, List list) { super( session ); this.list = list; setInitialized(); setDirectlyAccessible( true ); }
@Override public Object readIndex(ResultSet rs, String[] aliases, SessionImplementor session) throws HibernateException, SQLException { Object index = getIndexType().nullSafeGet( rs, aliases, session, null ); if ( index == null ) { throw new HibernateException( "null index column for collection: " + role ); } index = decrementIndexByBase( index ); return index; }
private Long getLastUpdateTimestampForSpace(Serializable space, SessionImplementor session) { Long ts = null; try { session.getEventListenerManager().cacheGetStart(); ts = (Long) region.get( space ); } finally { session.getEventListenerManager().cacheGetEnd( ts != null ); } return ts; }