@Override public final String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { final String entityName = criteriaQuery.getEntityName( criteria, propertyName ); final String actualPropertyName = criteriaQuery.getPropertyName( propertyName ); final String sqlAlias = criteriaQuery.getSQLAlias( criteria, propertyName ); final SessionFactoryImplementor factory = criteriaQuery.getFactory(); final QueryableCollection collectionPersister = getQueryableCollection( entityName, actualPropertyName, factory ); final String[] collectionKeys = collectionPersister.getKeyColumnNames(); final String[] ownerKeys = ( (Loadable) factory.getEntityPersister( entityName ) ).getIdentifierColumnNames(); final String innerSelect = "(select 1 from " + collectionPersister.getTableName() + " where " + new ConditionFragment().setTableAlias( sqlAlias ).setCondition( ownerKeys, collectionKeys ).toFragmentString() + ")"; return excludeEmpty() ? "exists " + innerSelect : "not exists " + innerSelect; }
@Override public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { final String entityName =criteriaQuery.getEntityName( criteria, propertyName ); final String role = entityName + '.' + criteriaQuery.getPropertyName( propertyName ); final QueryableCollection cp = (QueryableCollection) criteriaQuery.getFactory().getCollectionPersister( role ); final String[] fk = cp.getKeyColumnNames(); final String[] pk = ( (Loadable) cp.getOwnerEntityPersister() ).getIdentifierColumnNames(); final ConditionFragment subQueryRestriction = new ConditionFragment() .setTableAlias( criteriaQuery.getSQLAlias( criteria, propertyName ) ) .setCondition( pk, fk ); return String.format( "? %s (select count(*) from %s where %s)", op, cp.getTableName(), subQueryRestriction.toFragmentString() ); }
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 String[] determineKeyAlias(Loadable persister, String suffix) { final String[] aliases; final String[] keyColumnsCandidates = getUserProvidedAliases( persister.getIdentifierPropertyName(), null ); if ( keyColumnsCandidates == null ) { aliases = getUserProvidedAliases( "id", getIdentifierAliases(persister, suffix) ); } else { aliases = keyColumnsCandidates; } final String[] rtn = StringHelper.unquote( aliases, persister.getFactory().getDialect() ); intern( rtn ); return rtn; }
public SubselectFetch( //final String queryString, final String alias, final Loadable loadable, final QueryParameters queryParameters, final Set resultingEntityKeys, final Map namedParameterLocMap) { this.resultingEntityKeys = resultingEntityKeys; this.queryParameters = queryParameters; this.namedParameterLocMap = namedParameterLocMap; this.loadable = loadable; this.alias = alias; //TODO: ugly here: final String queryString = queryParameters.getFilteredSQL(); int fromIndex = queryString.indexOf( " from " ); int orderByIndex = queryString.lastIndexOf( "order by" ); this.queryString = orderByIndex > 0 ? queryString.substring( fromIndex, orderByIndex ) : queryString.substring( fromIndex ); }
public final String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { String entityName = criteriaQuery.getEntityName( criteria, propertyName ); String actualPropertyName = criteriaQuery.getPropertyName( propertyName ); String sqlAlias = criteriaQuery.getSQLAlias( criteria, propertyName ); SessionFactoryImplementor factory = criteriaQuery.getFactory(); QueryableCollection collectionPersister = getQueryableCollection( entityName, actualPropertyName, factory ); String[] collectionKeys = collectionPersister.getKeyColumnNames(); String[] ownerKeys = ( ( Loadable ) factory.getEntityPersister( entityName ) ).getIdentifierColumnNames(); String innerSelect = "(select 1 from " + collectionPersister.getTableName() + " where " + new ConditionFragment().setTableAlias( sqlAlias ).setCondition( ownerKeys, collectionKeys ).toFragmentString() + ")"; return excludeEmpty() ? "exists " + innerSelect : "not exists " + innerSelect; }
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { String role = criteriaQuery.getEntityName(criteria, propertyName) + '.' + criteriaQuery.getPropertyName(propertyName); QueryableCollection cp = (QueryableCollection) criteriaQuery.getFactory() .getCollectionPersister(role); //String[] fk = StringHelper.qualify( "collection_", cp.getKeyColumnNames() ); String[] fk = cp.getKeyColumnNames(); String[] pk = ( (Loadable) cp.getOwnerEntityPersister() ).getIdentifierColumnNames(); //TODO: handle property-ref return "? " + op + " (select count(*) from " + cp.getTableName() + //" collection_ where " + " where " + new ConditionFragment() .setTableAlias( criteriaQuery.getSQLAlias(criteria, propertyName) ) .setCondition(pk, fk) .toFragmentString() + ")"; }
public SubselectFetch( //final String queryString, final String alias, final Loadable loadable, final QueryParameters queryParameters, final Set resultingEntityKeys, final Map namedParameterLocMap ) { this.resultingEntityKeys = resultingEntityKeys; this.queryParameters = queryParameters; this.namedParameterLocMap = namedParameterLocMap; this.loadable = loadable; this.alias = alias; //TODO: ugly here: final String queryString = queryParameters.getFilteredSQL(); int fromIndex = queryString.indexOf(" from "); int orderByIndex = queryString.lastIndexOf("order by"); this.queryString = orderByIndex>0 ? queryString.substring(fromIndex, orderByIndex) : queryString.substring(fromIndex); }
protected final void initProjection( final String projectionString, final String whereString, final String orderByString, final String groupByString, final LockOptions lockOptions) throws MappingException { walkEntityTree( persister, getAlias() ); persisters = new Loadable[0]; initStatementString(projectionString, whereString, orderByString, groupByString, lockOptions); }
@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 hasSubselectLoadableCollections() { final Loadable[] loadables = getEntityPersisters(); for ( Loadable loadable : loadables ) { if ( loadable.hasSubselectLoadableCollections() ) { return true; } } return false; }
private void createSubselects(List keys, QueryParameters queryParameters, SessionImplementor session) { if ( keys.size() > 1 ) { //if we only returned one entity, query by key is more efficient Set[] keySets = transpose(keys); Map namedParameterLocMap = buildNamedParameterLocMap( queryParameters ); final Loadable[] loadables = getEntityPersisters(); final String[] aliases = getAliases(); final Iterator iter = keys.iterator(); while ( iter.hasNext() ) { final EntityKey[] rowKeys = (EntityKey[]) iter.next(); for ( int i=0; i<rowKeys.length; i++ ) { if ( rowKeys[i]!=null && loadables[i].hasSubselectLoadableCollections() ) { SubselectFetch subselectFetch = new SubselectFetch( //getSQLString(), aliases[i], loadables[i], queryParameters, keySets[i], namedParameterLocMap ); session.getPersistenceContext() .getBatchFetchQueue() .addSubselect( rowKeys[i], subselectFetch ); } } } } }
/** * Check the version of the object in the <tt>ResultSet</tt> against * the object version in the session cache, throwing an exception * if the version numbers are different */ private void checkVersion( final int i, final Loadable persister, final Serializable id, final Object entity, final ResultSet rs, final SessionImplementor session) throws HibernateException, SQLException { Object version = session.getPersistenceContext().getEntry( entity ).getVersion(); if ( version != null ) { //null version means the object is in the process of being loaded somewhere else in the ResultSet VersionType versionType = persister.getVersionType(); Object currentVersion = versionType.nullSafeGet( rs, getEntityAliases()[i].getSuffixedVersionAliases(), session, null ); if ( !versionType.isEqual(version, currentVersion) ) { if ( session.getFactory().getStatistics().isStatisticsEnabled() ) { session.getFactory().getStatisticsImplementor() .optimisticFailure( persister.getEntityName() ); } throw new StaleObjectStateException( persister.getEntityName(), id ); } } }
/** * The entity instance is already in the session cache */ private void instanceAlreadyLoaded( final ResultSet rs, final int i, final Loadable persister, final EntityKey key, final Object object, final LockMode requestedLockMode, final SessionImplementor session) throws HibernateException, SQLException { if ( !persister.isInstance( object ) ) { throw new WrongClassException( "loaded object was of wrong class " + object.getClass(), key.getIdentifier(), persister.getEntityName() ); } if ( LockMode.NONE != requestedLockMode && upgradeLocks() ) { //no point doing this if NONE was requested final EntityEntry entry = session.getPersistenceContext().getEntry( object ); if ( entry.getLockMode().lessThan( requestedLockMode ) ) { //we only check the version when _upgrading_ lock modes if ( persister.isVersioned() ) { checkVersion( i, persister, key.getIdentifier(), object, rs, session ); } //we need to upgrade the lock mode to the mode requested entry.setLockMode( requestedLockMode ); } } }
/** * Determine the concrete class of an instance in the <tt>ResultSet</tt> */ private String getInstanceClass( final ResultSet rs, final int i, final Loadable persister, final Serializable id, final SessionImplementor session) throws HibernateException, SQLException { if ( persister.hasSubclasses() ) { // Code to handle subclasses of topClass Object discriminatorValue = persister.getDiscriminatorType().nullSafeGet( rs, getEntityAliases()[i].getSuffixedDiscriminatorAlias(), session, null ); final String result = persister.getSubclassForDiscriminatorValue( discriminatorValue ); if ( result == null ) { //woops we got an instance of another class hierarchy branch throw new WrongClassException( "Discriminator: " + discriminatorValue, id, persister.getEntityName() ); } return result; } else { return persister.getEntityName(); } }
private void createSubselects() { if ( subselectLoadableEntityKeyMap == null || subselectLoadableEntityKeyMap.size() <= 1 ) { // if we only returned one entity, query by key is more efficient; so do nothing here return; } final Map<String, int[]> namedParameterLocMap = ResultSetProcessorHelper.buildNamedParameterLocMap( queryParameters, namedParameterContext ); for ( Map.Entry<EntityPersister, Set<EntityKey>> entry : subselectLoadableEntityKeyMap.entrySet() ) { if ( ! entry.getKey().hasSubselectLoadableCollections() ) { continue; } SubselectFetch subselectFetch = new SubselectFetch( //getSQLString(), null, // aliases[i], (Loadable) entry.getKey(), queryParameters, entry.getValue(), namedParameterLocMap ); for ( EntityKey key : entry.getValue() ) { session.getPersistenceContext().getBatchFetchQueue().addSubselect( key, subselectFetch ); } } }
private void postLoad( PostLoadEvent postLoadEvent, ResultSetProcessingContextImpl context, List<HydratedEntityRegistration> hydratedEntityRegistrations, List<AfterLoadAction> afterLoadActionList) { // Until this entire method is refactored w/ polymorphism, postLoad was // split off from initializeEntity. It *must* occur after // endCollectionLoad to ensure the collection is in the // persistence context. if ( hydratedEntityRegistrations == null ) { return; } for ( HydratedEntityRegistration registration : hydratedEntityRegistrations ) { TwoPhaseLoad.postLoad( registration.getInstance(), context.getSession(), postLoadEvent ); if ( afterLoadActionList != null ) { for ( AfterLoadAction afterLoadAction : afterLoadActionList ) { afterLoadAction.afterLoad( context.getSession(), registration.getInstance(), (Loadable) registration.getEntityReference().getEntityPersister() ); } } } }
private String getConcreteEntityTypeName( ResultSet resultSet, ResultSetProcessingContext context, EntityKey entityKey) { final Loadable loadable = (Loadable) entityReference.getEntityPersister(); if ( ! loadable.hasSubclasses() ) { return entityReference.getEntityPersister().getEntityName(); } final Object discriminatorValue; try { discriminatorValue = loadable.getDiscriminatorType().nullSafeGet( resultSet, entityReferenceAliases.getColumnAliases().getSuffixedDiscriminatorAlias(), context.getSession(), null ); } catch (SQLException e) { throw context.getSession().getFactory().getJdbcServices().getSqlExceptionHelper().convert( e, "Could not read discriminator value from ResultSet" ); } final String result = loadable.getSubclassForDiscriminatorValue( discriminatorValue ); if ( result == null ) { // whoops! we got an instance of another class hierarchy branch throw new WrongClassException( "Discriminator: " + discriminatorValue, entityKey.getIdentifier(), entityReference.getEntityPersister().getEntityName() ); } return result; }
/** * Calculate and cache select-clause aliases * * @param userProvidedAliases The explicit aliases provided in a result-set mapping. * @param persister The persister for which we are generating select aliases * @param suffix The calculated suffix. */ public DefaultEntityAliases( Map userProvidedAliases, Loadable persister, String suffix) { this.suffix = suffix; this.userProvidedAliases = userProvidedAliases; suffixedKeyColumns = determineKeyAlias( persister, suffix ); suffixedPropertyColumns = determinePropertyAliases( persister ); suffixedDiscriminatorColumn = determineDiscriminatorAlias( persister, suffix ); suffixedVersionColumn = determineVersionAlias( persister ); rowIdAlias = Loadable.ROWID_ALIAS + suffix; // TODO: not visible to the user! }
@Override public String[][] getSuffixedPropertyAliases(Loadable persister) { final int size = persister.getPropertyNames().length; final String[][] suffixedPropertyAliases = new String[size][]; for ( int j = 0; j < size; j++ ) { suffixedPropertyAliases[j] = getUserProvidedAliases( persister.getPropertyNames()[j], getPropertyAliases( persister, j ) ); suffixedPropertyAliases[j] = StringHelper.unquote( suffixedPropertyAliases[j], persister.getFactory().getDialect() ); intern( suffixedPropertyAliases[j] ); } return suffixedPropertyAliases; }
@Override public String resolveTableAlias(String columnReference) { if ( elementPersister == null ) { // we have collection of non-entity elements... return rootAlias; } else { return ( (Loadable) elementPersister ).getTableAliasForColumn( columnReference, rootAlias ); } }
protected final void initProjection( final String projectionString, final String whereString, final String orderByString, final String groupByString, final LockMode lockMode) throws MappingException { walkEntityTree( persister, getAlias() ); persisters = new Loadable[0]; initStatementString(projectionString, whereString, orderByString, groupByString, lockMode); }
protected void postInstantiate() { Loadable[] persisters = getEntityPersisters(); String[] suffixes = getSuffixes(); descriptors = new EntityAliases[persisters.length]; for ( int i=0; i<descriptors.length; i++ ) { descriptors[i] = new DefaultEntityAliases( persisters[i], suffixes[i] ); } CollectionPersister[] collectionPersisters = getCollectionPersisters(); int bagCount = 0; if ( collectionPersisters != null ) { String[] collectionSuffixes = getCollectionSuffixes(); collectionDescriptors = new CollectionAliases[collectionPersisters.length]; for ( int i = 0; i < collectionPersisters.length; i++ ) { if ( isBag( collectionPersisters[i] ) ) { bagCount++; } collectionDescriptors[i] = new GeneratedCollectionAliases( collectionPersisters[i], collectionSuffixes[i] ); } } else { collectionDescriptors = null; } if ( bagCount > 1 ) { throw new HibernateException( "cannot simultaneously fetch multiple bags" ); } }
public TypedValue getTypedIdentifierValue(Criteria subcriteria, Object value) { final Loadable loadable = ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) ); return new TypedValue( loadable.getIdentifierType(), value, EntityMode.POJO ); }
protected boolean hasSubselectLoadableCollections() { final Loadable[] loadables = getEntityPersisters(); for (int i=0; i<loadables.length; i++ ) { if ( loadables[i].hasSubselectLoadableCollections() ) return true; } return false; }
/** * Read a row of <tt>Key</tt>s from the <tt>ResultSet</tt> into the given array. * Warning: this method is side-effecty. * <p/> * If an <tt>id</tt> is given, don't bother going to the <tt>ResultSet</tt>. */ private EntityKey getKeyFromResultSet( final int i, final Loadable persister, final Serializable id, final ResultSet rs, final SessionImplementor session) throws HibernateException, SQLException { Serializable resultId; // if we know there is exactly 1 row, we can skip. // it would be great if we could _always_ skip this; // it is a problem for <key-many-to-one> if ( isSingleRowLoader() && id != null ) { resultId = id; } else { Type idType = persister.getIdentifierType(); resultId = (Serializable) idType.nullSafeGet( rs, getEntityAliases()[i].getSuffixedKeyAliases(), session, null //problematic for <key-many-to-one>! ); final boolean idIsResultId = id != null && resultId != null && idType.isEqual( id, resultId, session.getEntityMode(), factory ); if ( idIsResultId ) resultId = id; //use the id passed in } return resultId == null ? null : new EntityKey( resultId, persister, session.getEntityMode() ); }
/** * The entity instance is already in the session cache */ private void instanceAlreadyLoaded( final ResultSet rs, final int i, final Loadable persister, final EntityKey key, final Object object, final LockMode lockMode, final SessionImplementor session) throws HibernateException, SQLException { if ( !persister.isInstance( object, session.getEntityMode() ) ) { throw new WrongClassException( "loaded object was of wrong class " + object.getClass(), key.getIdentifier(), persister.getEntityName() ); } if ( LockMode.NONE != lockMode && upgradeLocks() ) { //no point doing this if NONE was requested final boolean isVersionCheckNeeded = persister.isVersioned() && session.getPersistenceContext().getEntry(object) .getLockMode().lessThan( lockMode ); // we don't need to worry about existing version being uninitialized // because this block isn't called by a re-entrant load (re-entrant // loads _always_ have lock mode NONE) if (isVersionCheckNeeded) { //we only check the version when _upgrading_ lock modes checkVersion( i, persister, key.getIdentifier(), object, rs, session ); //we need to upgrade the lock mode to the mode requested session.getPersistenceContext().getEntry(object) .setLockMode(lockMode); } } }
/** * Calculate and cache select-clause suffixes. * @param map */ public DefaultEntityAliases(Map userProvidedAliases, Loadable persister, String suffix) { this.suffix = suffix; this.userProvidedAliases = userProvidedAliases; String[] keyColumnsCandidates = getUserProvidedAliases( persister.getIdentifierPropertyName(), (String[]) null ); if (keyColumnsCandidates==null) { suffixedKeyColumns = getUserProvidedAliases( "id", getIdentifierAliases(persister, suffix) ); } else { suffixedKeyColumns = keyColumnsCandidates; } intern(suffixedKeyColumns); suffixedPropertyColumns = getSuffixedPropertyAliases(persister); suffixedDiscriminatorColumn = getUserProvidedAlias( "class", getDiscriminatorAlias(persister, suffix) ); if ( persister.isVersioned() ) { suffixedVersionColumn = suffixedPropertyColumns[ persister.getVersionProperty() ]; } else { suffixedVersionColumn = null; } rowIdAlias = Loadable.ROWID_ALIAS + suffix; // TODO: not visible to the user! }
public String[][] getSuffixedPropertyAliases(Loadable persister) { int size = persister.getPropertyNames().length; String[][] suffixedPropertyAliases = new String[size][]; for ( int j = 0; j < size; j++ ) { suffixedPropertyAliases[j] = getUserProvidedAliases( persister.getPropertyNames()[j], getPropertyAliases(persister, j) ); intern( suffixedPropertyAliases[j] ); } return suffixedPropertyAliases; }
@Override public Object[] hydrate(ResultSet rs, Serializable id, Object object, Loadable rootLoadable, String[][] suffixedPropertyColumns, boolean allProperties, SharedSessionContractImplementor session) throws SQLException, HibernateException { Object[] values = super.hydrate(rs, id, object, rootLoadable, suffixedPropertyColumns, allProperties, session); MidpointPersisterUtil.killUnwantedAssociationValues(getPropertyNames(), getPropertyTypes(), values); return values; }
public final Loadable getPersister() { return persister; }
public ColumnEntityAliases( Map returnProperties, Loadable persister, String suffix) { super( returnProperties, persister, suffix ); }
protected String[] getIdentifierAliases(Loadable persister, String suffix) { return persister.getIdentifierColumnNames(); }
protected String getDiscriminatorAlias(Loadable persister, String suffix) { return persister.getDiscriminatorColumnName(); }