下面列出了怎么用org.hibernate.sql.Select的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Generate the {@code INSERT}-{@code SELECT} statement for holding matching ids. This is the
* {@code INSERT} used to populate the bulk-id table with ids matching the restrictions defined in the
* original {@code WHERE} clause
*
* @param tableAlias The table alias to use for the entity
* @param whereClause The processed representation for the user-defined {@code WHERE} clause.
*
* @return The {@code INSERT}-{@code SELECT} for populating the bulk-id table.
*/
protected String generateIdInsertSelect(
String tableAlias,
IdTableInfo idTableInfo,
ProcessedWhereClause whereClause) {
final Dialect dialect = sessionFactory.getJdbcServices().getJdbcEnvironment().getDialect();
final Select select = generateIdSelect( tableAlias, whereClause );
InsertSelect insert = new InsertSelect( dialect );
if ( sessionFactory.getSessionFactoryOptions().isCommentsEnabled() ) {
insert.setComment( "insert-select for " + getTargetedQueryable().getEntityName() + " ids" );
}
insert.setTableName( idTableInfo.getQualifiedIdTableName() );
insert.setSelect( select );
return insert.toStatementString();
}
private void initStatementString(
final String projection,
final String condition,
final String orderBy,
final String groupBy,
final LockOptions lockOptions) throws MappingException {
final int joins = countEntityPersisters( associations );
suffixes = BasicLoader.generateSuffixes( joins + 1 );
JoinFragment ojf = mergeOuterJoins( associations );
Select select = new Select( getDialect() )
.setLockOptions( lockOptions )
.setSelectClause(
projection == null ?
persister.selectFragment( alias, suffixes[joins] ) + selectString( associations ) :
projection
)
.setFromClause(
getDialect().appendLockHint( lockOptions, persister.fromTableFragment( alias ) ) +
persister.fromJoinFragment( alias, true, true )
)
.setWhereClause( condition )
.setOuterJoins(
ojf.toFromFragmentString(),
ojf.toWhereFragmentString() + getWhereFragment()
)
.setOrderByClause( orderBy( associations, orderBy ) )
.setGroupByClause( groupBy );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
select.setComment( getComment() );
}
sql = select.toStatementString();
}
protected String generateSnapshotSelectString() {
//TODO: should we use SELECT .. FOR UPDATE?
Select select = new Select( getFactory().getDialect() );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
select.setComment( "get current state " + getEntityName() );
}
String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
String selectClause = String.join( ", ", aliasedIdColumns ) +
concretePropertySelectFragment( getRootAlias(), getPropertyUpdateability() );
String fromClause = fromTableFragment( getRootAlias() ) +
fromJoinFragment( getRootAlias(), true, false );
String whereClause = new StringBuilder()
.append(
String.join(
"=? and ",
aliasedIdColumns
)
)
.append( "=?" )
.append( whereJoinFragment( getRootAlias(), true, false ) )
.toString();
/*if ( isVersioned() ) {
where.append(" and ")
.append( getVersionColumnName() )
.append("=?");
}*/
return select.setSelectClause( selectClause )
.setFromClause( fromClause )
.setOuterJoins( "", "" )
.setWhereClause( whereClause )
.toStatementString();
}
protected String renderSelect(
final int[] tableNumbers,
final int[] columnNumbers,
final int[] formulaNumbers) {
Arrays.sort( tableNumbers ); //get 'em in the right order (not that it really matters)
//render the where and from parts
int drivingTable = tableNumbers[0];
final String drivingAlias = generateTableAlias(
getRootAlias(),
drivingTable
); //we *could* regerate this inside each called method!
final String where = createWhereByKey( drivingTable, drivingAlias );
final String from = createFrom( drivingTable, drivingAlias );
//now render the joins
JoinFragment jf = createJoin( tableNumbers, drivingAlias );
//now render the select clause
SelectFragment selectFragment = createSelect( columnNumbers, formulaNumbers );
//now tie it all together
Select select = new Select( getFactory().getDialect() );
select.setSelectClause( selectFragment.toFragmentString().substring( 2 ) );
select.setFromClause( from );
select.setWhereClause( where );
select.setOuterJoins( jf.toFromFragmentString(), jf.toWhereFragmentString() );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
select.setComment( "sequential select " + getEntityName() );
}
return select.toStatementString();
}
protected Select generateIdSelect(
String tableAlias,
ProcessedWhereClause whereClause) {
final Dialect dialect = sessionFactory.getJdbcServices().getJdbcEnvironment().getDialect();
final Select select = new Select( dialect );
final SelectValues selectClause = new SelectValues( dialect ).addColumns(
tableAlias,
getTargetedQueryable().getIdentifierColumnNames(),
getTargetedQueryable().getIdentifierColumnNames()
);
addAnyExtraIdSelectValues( selectClause );
select.setSelectClause( selectClause.render() );
String rootTableName = getTargetedQueryable().getTableName();
String fromJoinFragment = getTargetedQueryable().fromJoinFragment( tableAlias, true, false );
String whereJoinFragment = getTargetedQueryable().whereJoinFragment( tableAlias, true, false );
select.setFromClause( rootTableName + ' ' + tableAlias + fromJoinFragment );
if ( whereJoinFragment == null ) {
whereJoinFragment = "";
}
else {
whereJoinFragment = whereJoinFragment.trim();
if ( whereJoinFragment.startsWith( "and" ) ) {
whereJoinFragment = whereJoinFragment.substring( 4 );
}
}
if ( whereClause.getUserWhereClauseFragment().length() > 0 ) {
if ( whereJoinFragment.length() > 0 ) {
whereJoinFragment += " and ";
}
}
select.setWhereClause( whereJoinFragment + whereClause.getUserWhereClauseFragment() );
return select;
}
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
final SessionImplementor session = ( (CriteriaImpl) criteria ).getSession(); //ugly!
final SessionFactoryImplementor factory = session.getFactory();
final OuterJoinLoadable persister = (OuterJoinLoadable) factory.getEntityPersister( criteriaImpl.getEntityOrClassName() );
CriteriaQueryTranslator innerQuery = new CriteriaQueryTranslator(
factory,
criteriaImpl,
criteriaImpl.getEntityOrClassName(), //implicit polymorphism not supported (would need a union)
criteriaQuery.generateSQLAlias(),
criteriaQuery
);
params = innerQuery.getQueryParameters(); //TODO: bad lifecycle....
types = innerQuery.getProjectedTypes();
//String filter = persister.filterFragment( innerQuery.getRootSQLALias(), session.getEnabledFilters() );
String sql = new Select( factory.getDialect() )
.setWhereClause( innerQuery.getWhereCondition() )
.setGroupByClause( innerQuery.getGroupBy() )
.setSelectClause( innerQuery.getSelect() )
.setFromClause(
persister.fromTableFragment( innerQuery.getRootSQLALias() ) +
persister.fromJoinFragment( innerQuery.getRootSQLALias(), true, false )
)
.toStatementString();
final StringBuffer buf = new StringBuffer()
.append( toLeftSqlString(criteria, criteriaQuery) );
if (op!=null) buf.append(' ').append(op).append(' ');
if (quantifier!=null) buf.append(quantifier).append(' ');
return buf.append('(').append(sql).append(')')
.toString();
}
private void initStatementString(
final String projection,
final String condition,
final String orderBy,
final String groupBy,
final LockMode lockMode) throws MappingException {
final int joins = countEntityPersisters( associations );
suffixes = BasicLoader.generateSuffixes( joins + 1 );
JoinFragment ojf = mergeOuterJoins( associations );
Select select = new Select( getDialect() )
.setLockMode( lockMode )
.setSelectClause(
projection == null ?
persister.selectFragment( alias, suffixes[joins] ) + selectString( associations ) :
projection
)
.setFromClause(
getDialect().appendLockHint( lockMode, persister.fromTableFragment( alias ) ) +
persister.fromJoinFragment( alias, true, true )
)
.setWhereClause( condition )
.setOuterJoins(
ojf.toFromFragmentString(),
ojf.toWhereFragmentString() + getWhereFragment()
)
.setOrderByClause( orderBy( associations, orderBy ) )
.setGroupByClause( groupBy );
if ( getFactory().getSettings().isCommentsEnabled() ) {
select.setComment( getComment() );
}
sql = select.toStatementString();
}
private String generateGeneratedValuesSelectString(ValueInclusion[] inclusions) {
Select select = new Select( getFactory().getDialect() );
if ( getFactory().getSettings().isCommentsEnabled() ) {
select.setComment( "get generated state " + getEntityName() );
}
String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
// Here we render the select column list based on the properties defined as being generated.
// For partial component generation, we currently just re-select the whole component
// rather than trying to handle the individual generated portions.
String selectClause = concretePropertySelectFragment( getRootAlias(), inclusions );
selectClause = selectClause.substring( 2 );
String fromClause = fromTableFragment( getRootAlias() ) +
fromJoinFragment( getRootAlias(), true, false );
String whereClause = new StringBuffer()
.append( StringHelper.join( "=? and ", aliasedIdColumns ) )
.append( "=?" )
.append( whereJoinFragment( getRootAlias(), true, false ) )
.toString();
return select.setSelectClause( selectClause )
.setFromClause( fromClause )
.setOuterJoins( "", "" )
.setWhereClause( whereClause )
.toStatementString();
}
protected String generateSnapshotSelectString() {
//TODO: should we use SELECT .. FOR UPDATE?
Select select = new Select( getFactory().getDialect() );
if ( getFactory().getSettings().isCommentsEnabled() ) {
select.setComment( "get current state " + getEntityName() );
}
String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
String selectClause = StringHelper.join( ", ", aliasedIdColumns ) +
concretePropertySelectFragment( getRootAlias(), getPropertyUpdateability() );
String fromClause = fromTableFragment( getRootAlias() ) +
fromJoinFragment( getRootAlias(), true, false );
String whereClause = new StringBuffer()
.append( StringHelper.join( "=? and ",
aliasedIdColumns ) )
.append( "=?" )
.append( whereJoinFragment( getRootAlias(), true, false ) )
.toString();
/*if ( isVersioned() ) {
where.append(" and ")
.append( getVersionColumnName() )
.append("=?");
}*/
return select.setSelectClause( selectClause )
.setFromClause( fromClause )
.setOuterJoins( "", "" )
.setWhereClause( whereClause )
.toStatementString();
}
protected String renderSelect(
final int[] tableNumbers,
final int[] columnNumbers,
final int[] formulaNumbers) {
Arrays.sort( tableNumbers ); //get 'em in the right order (not that it really matters)
//render the where and from parts
int drivingTable = tableNumbers[0];
final String drivingAlias = generateTableAlias( getRootAlias(), drivingTable ); //we *could* regerate this inside each called method!
final String where = createWhereByKey( drivingTable, drivingAlias );
final String from = createFrom( drivingTable, drivingAlias );
//now render the joins
JoinFragment jf = createJoin( tableNumbers, drivingAlias );
//now render the select clause
SelectFragment selectFragment = createSelect( columnNumbers, formulaNumbers );
//now tie it all together
Select select = new Select( getFactory().getDialect() );
select.setSelectClause( selectFragment.toFragmentString().substring( 2 ) );
select.setFromClause( from );
select.setWhereClause( where );
select.setOuterJoins( jf.toFromFragmentString(), jf.toWhereFragmentString() );
if ( getFactory().getSettings().isCommentsEnabled() ) {
select.setComment( "sequential select " + getEntityName() );
}
return select.toStatementString();
}
private void initStatementString(
final String alias,
final int batchSize,
final String subquery) throws MappingException {
final int joins = countEntityPersisters( associations );
final int collectionJoins = countCollectionPersisters( associations ) + 1;
suffixes = BasicLoader.generateSuffixes( joins );
collectionSuffixes = BasicLoader.generateSuffixes( joins, collectionJoins );
StringBuilder whereString = whereString(
alias,
collectionPersister.getKeyColumnNames(),
subquery,
batchSize
);
String manyToManyOrderBy = "";
String filter = collectionPersister.filterFragment( alias, getLoadQueryInfluencers().getEnabledFilters() );
if ( collectionPersister.isManyToMany() ) {
// from the collection of associations, locate OJA for the
// ManyToOne corresponding to this persister to fully
// define the many-to-many; we need that OJA so that we can
// use its alias here
// TODO : is there a better way here?
Iterator itr = associations.iterator();
AssociationType associationType = ( AssociationType ) collectionPersister.getElementType();
while ( itr.hasNext() ) {
OuterJoinableAssociation oja = ( OuterJoinableAssociation ) itr.next();
if ( oja.getJoinableType() == associationType ) {
// we found it
filter += collectionPersister.getManyToManyFilterFragment(
oja.getRHSAlias(),
getLoadQueryInfluencers().getEnabledFilters()
);
manyToManyOrderBy += collectionPersister.getManyToManyOrderByString( oja.getRHSAlias() );
}
}
}
whereString.insert( 0, StringHelper.moveAndToBeginning( filter ) );
JoinFragment ojf = mergeOuterJoins(associations);
Select select = new Select( getDialect() )
.setSelectClause(
collectionPersister.selectFragment(alias, collectionSuffixes[0] ) +
selectString(associations)
)
.setFromClause( collectionPersister.getTableName(), alias )
.setWhereClause( whereString.toString() )
.setOuterJoins(
ojf.toFromFragmentString(),
ojf.toWhereFragmentString()
);
select.setOrderByClause( orderBy( associations, mergeOrderings( collectionPersister.getSQLOrderByString(alias), manyToManyOrderBy ) ) );
if ( getFactory().getSettings().isCommentsEnabled() ) {
select.setComment( "load collection " + collectionPersister.getRole() );
}
sql = select.toStatementString();
}
private void initStatementString(
final OuterJoinLoadable elementPersister,
final String alias,
final int batchSize,
final String subquery)
throws MappingException {
final int joins = countEntityPersisters( associations );
suffixes = BasicLoader.generateSuffixes( joins + 1 );
final int collectionJoins = countCollectionPersisters( associations ) + 1;
collectionSuffixes = BasicLoader.generateSuffixes( joins + 1, collectionJoins );
StringBuilder whereString = whereString(
alias,
oneToManyPersister.getKeyColumnNames(),
subquery,
batchSize
);
String filter = oneToManyPersister.filterFragment( alias, getLoadQueryInfluencers().getEnabledFilters() );
whereString.insert( 0, StringHelper.moveAndToBeginning( filter ) );
JoinFragment ojf = mergeOuterJoins( associations );
Select select = new Select( getDialect() )
.setSelectClause(
oneToManyPersister.selectFragment(
null,
null,
alias,
suffixes[joins],
collectionSuffixes[0],
true
) +
selectString( associations )
)
.setFromClause(
elementPersister.fromTableFragment( alias ) +
elementPersister.fromJoinFragment( alias, true, true )
)
.setWhereClause( whereString.toString() )
.setOuterJoins(
ojf.toFromFragmentString(),
ojf.toWhereFragmentString() +
elementPersister.whereJoinFragment( alias, true, true )
);
select.setOrderByClause( orderBy( associations, oneToManyPersister.getSQLOrderByString( alias ) ) );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
select.setComment( "load one-to-many " + oneToManyPersister.getRole() );
}
sql = select.toStatementString();
}
protected String generateIdByUniqueKeySelectString(String uniquePropertyName) {
Select select = new Select( getFactory().getDialect() );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
select.setComment( "resolve id by unique property [" + getEntityName() + "." + uniquePropertyName + "]" );
}
final String rooAlias = getRootAlias();
select.setFromClause( fromTableFragment( rooAlias ) + fromJoinFragment( rooAlias, true, false ) );
SelectFragment selectFragment = new SelectFragment();
selectFragment.addColumns( rooAlias, getIdentifierColumnNames(), getIdentifierAliases() );
select.setSelectClause( selectFragment );
StringBuilder whereClauseBuffer = new StringBuilder();
final int uniquePropertyIndex = getSubclassPropertyIndex( uniquePropertyName );
final String uniquePropertyTableAlias = generateTableAlias(
rooAlias,
getSubclassPropertyTableNumber( uniquePropertyIndex )
);
String sep = "";
for ( String columnTemplate : getSubclassPropertyColumnReaderTemplateClosure()[uniquePropertyIndex] ) {
if ( columnTemplate == null ) {
continue;
}
final String columnReference = StringHelper.replace(
columnTemplate,
Template.TEMPLATE,
uniquePropertyTableAlias
);
whereClauseBuffer.append( sep ).append( columnReference ).append( "=?" );
sep = " and ";
}
for ( String formulaTemplate : getSubclassPropertyFormulaTemplateClosure()[uniquePropertyIndex] ) {
if ( formulaTemplate == null ) {
continue;
}
final String formulaReference = StringHelper.replace(
formulaTemplate,
Template.TEMPLATE,
uniquePropertyTableAlias
);
whereClauseBuffer.append( sep ).append( formulaReference ).append( "=?" );
sep = " and ";
}
whereClauseBuffer.append( whereJoinFragment( rooAlias, true, false ) );
select.setWhereClause( whereClauseBuffer.toString() );
return select.setOuterJoins( "", "" ).toStatementString();
}
private String generateGeneratedValuesSelectString(final GenerationTiming generationTimingToMatch) {
Select select = new Select( getFactory().getDialect() );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
select.setComment( "get generated state " + getEntityName() );
}
String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
// Here we render the select column list based on the properties defined as being generated.
// For partial component generation, we currently just re-select the whole component
// rather than trying to handle the individual generated portions.
String selectClause = concretePropertySelectFragment(
getRootAlias(),
new InclusionChecker() {
@Override
public boolean includeProperty(int propertyNumber) {
final InDatabaseValueGenerationStrategy generationStrategy
= entityMetamodel.getInDatabaseValueGenerationStrategies()[propertyNumber];
return generationStrategy != null
&& timingsMatch( generationStrategy.getGenerationTiming(), generationTimingToMatch );
}
}
);
selectClause = selectClause.substring( 2 );
String fromClause = fromTableFragment( getRootAlias() ) +
fromJoinFragment( getRootAlias(), true, false );
String whereClause = new StringBuilder()
.append( String.join( "=? and ", aliasedIdColumns ) )
.append( "=?" )
.append( whereJoinFragment( getRootAlias(), true, false ) )
.toString();
return select.setSelectClause( selectClause )
.setFromClause( fromClause )
.setOuterJoins( "", "" )
.setWhereClause( whereClause )
.toStatementString();
}
public Object[] getNaturalIdentifierSnapshot(Serializable id, SharedSessionContractImplementor session)
throws HibernateException {
if ( !hasNaturalIdentifier() ) {
throw new MappingException(
"persistent class did not define a natural-id : " + MessageHelper.infoString(
this
)
);
}
if ( LOG.isTraceEnabled() ) {
LOG.tracev(
"Getting current natural-id snapshot state for: {0}",
MessageHelper.infoString( this, id, getFactory() )
);
}
int[] naturalIdPropertyIndexes = getNaturalIdentifierProperties();
int naturalIdPropertyCount = naturalIdPropertyIndexes.length;
boolean[] naturalIdMarkers = new boolean[getPropertySpan()];
Type[] extractionTypes = new Type[naturalIdPropertyCount];
for ( int i = 0; i < naturalIdPropertyCount; i++ ) {
extractionTypes[i] = getPropertyTypes()[naturalIdPropertyIndexes[i]];
naturalIdMarkers[naturalIdPropertyIndexes[i]] = true;
}
///////////////////////////////////////////////////////////////////////
// TODO : look at perhaps caching this...
Select select = new Select( getFactory().getDialect() );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
select.setComment( "get current natural-id state " + getEntityName() );
}
select.setSelectClause( concretePropertySelectFragmentSansLeadingComma( getRootAlias(), naturalIdMarkers ) );
select.setFromClause( fromTableFragment( getRootAlias() ) + fromJoinFragment( getRootAlias(), true, false ) );
String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
String whereClause = new StringBuilder()
.append(
String.join(
"=? and ",
aliasedIdColumns
)
)
.append( "=?" )
.append( whereJoinFragment( getRootAlias(), true, false ) )
.toString();
String sql = select.setOuterJoins( "", "" )
.setWhereClause( whereClause )
.toStatementString();
///////////////////////////////////////////////////////////////////////
Object[] snapshot = new Object[naturalIdPropertyCount];
try {
PreparedStatement ps = session
.getJdbcCoordinator()
.getStatementPreparer()
.prepareStatement( sql );
try {
getIdentifierType().nullSafeSet( ps, id, 1, session );
ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( ps );
try {
//if there is no resulting row, return null
if ( !rs.next() ) {
return null;
}
final EntityKey key = session.generateEntityKey( id, this );
Object owner = session.getPersistenceContext().getEntity( key );
for ( int i = 0; i < naturalIdPropertyCount; i++ ) {
snapshot[i] = extractionTypes[i].hydrate(
rs, getPropertyAliases(
"",
naturalIdPropertyIndexes[i]
), session, null
);
if ( extractionTypes[i].isEntityType() ) {
snapshot[i] = extractionTypes[i].resolve( snapshot[i], session, owner );
}
}
return snapshot;
}
finally {
session.getJdbcCoordinator().getResourceRegistry().release( rs, ps );
}
}
finally {
session.getJdbcCoordinator().getResourceRegistry().release( ps );
session.getJdbcCoordinator().afterStatementExecution();
}
}
catch (SQLException e) {
throw getFactory().getSQLExceptionHelper().convert(
e,
"could not retrieve snapshot: " + MessageHelper.infoString( this, id, getFactory() ),
sql
);
}
}
private String generateEntityIdByNaturalIdSql(boolean[] valueNullness) {
EntityPersister rootPersister = getFactory().getEntityPersister( getRootEntityName() );
if ( rootPersister != this ) {
if ( rootPersister instanceof AbstractEntityPersister ) {
return ( (AbstractEntityPersister) rootPersister ).generateEntityIdByNaturalIdSql( valueNullness );
}
}
Select select = new Select( getFactory().getDialect() );
if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) {
select.setComment( "get current natural-id->entity-id state " + getEntityName() );
}
final String rootAlias = getRootAlias();
select.setSelectClause( identifierSelectFragment( rootAlias, "" ) );
select.setFromClause( fromTableFragment( rootAlias ) + fromJoinFragment( rootAlias, true, false ) );
final StringBuilder whereClause = new StringBuilder();
final int[] propertyTableNumbers = getPropertyTableNumbers();
final int[] naturalIdPropertyIndexes = this.getNaturalIdentifierProperties();
int valuesIndex = -1;
for ( int propIdx = 0; propIdx < naturalIdPropertyIndexes.length; propIdx++ ) {
valuesIndex++;
if ( propIdx > 0 ) {
whereClause.append( " and " );
}
final int naturalIdIdx = naturalIdPropertyIndexes[propIdx];
final String tableAlias = generateTableAlias( rootAlias, propertyTableNumbers[naturalIdIdx] );
final String[] propertyColumnNames = getPropertyColumnNames( naturalIdIdx );
final String[] aliasedPropertyColumns = StringHelper.qualify( tableAlias, propertyColumnNames );
if ( valueNullness != null && valueNullness[valuesIndex] ) {
whereClause.append( String.join( " is null and ", aliasedPropertyColumns ) ).append( " is null" );
}
else {
whereClause.append( String.join( "=? and ", aliasedPropertyColumns ) ).append( "=?" );
}
}
whereClause.append( whereJoinFragment( getRootAlias(), true, false ) );
return select.setOuterJoins( "", "" ).setWhereClause( whereClause.toString() ).toStatementString();
}
private void initStatementString(
final String alias,
final int batchSize,
final String subquery)
throws MappingException {
final int joins = countEntityPersisters( associations );
final int collectionJoins = countCollectionPersisters( associations ) + 1;
suffixes = BasicLoader.generateSuffixes( joins );
collectionSuffixes = BasicLoader.generateSuffixes( joins, collectionJoins );
StringBuffer whereString = whereString(
alias,
collectionPersister.getKeyColumnNames(),
subquery,
batchSize
);
String manyToManyOrderBy = "";
String filter = collectionPersister.filterFragment( alias, getEnabledFilters() );
if ( collectionPersister.isManyToMany() ) {
// from the collection of associations, locate OJA for the
// ManyToOne corresponding to this persister to fully
// define the many-to-many; we need that OJA so that we can
// use its alias here
// TODO : is there a better way here?
Iterator itr = associations.iterator();
AssociationType associationType = ( AssociationType ) collectionPersister.getElementType();
while ( itr.hasNext() ) {
OuterJoinableAssociation oja = ( OuterJoinableAssociation ) itr.next();
if ( oja.getJoinableType() == associationType ) {
// we found it
filter += collectionPersister.getManyToManyFilterFragment(
oja.getRHSAlias(),
getEnabledFilters()
);
manyToManyOrderBy += collectionPersister.getManyToManyOrderByString( oja.getRHSAlias() );
}
}
}
whereString.insert( 0, StringHelper.moveAndToBeginning( filter ) );
JoinFragment ojf = mergeOuterJoins(associations);
Select select = new Select( getDialect() )
.setSelectClause(
collectionPersister.selectFragment(alias, collectionSuffixes[0] ) +
selectString(associations)
)
.setFromClause( collectionPersister.getTableName(), alias )
.setWhereClause( whereString.toString() )
.setOuterJoins(
ojf.toFromFragmentString(),
ojf.toWhereFragmentString()
);
select.setOrderByClause( orderBy( associations, mergeOrderings( collectionPersister.getSQLOrderByString(alias), manyToManyOrderBy ) ) );
if ( getFactory().getSettings().isCommentsEnabled() ) {
select.setComment( "load collection " + collectionPersister.getRole() );
}
sql = select.toStatementString();
}
private void initStatementString(
final OuterJoinLoadable elementPersister,
final String alias,
final int batchSize,
final String subquery)
throws MappingException {
final int joins = countEntityPersisters( associations );
suffixes = BasicLoader.generateSuffixes( joins + 1 );
final int collectionJoins = countCollectionPersisters( associations ) + 1;
collectionSuffixes = BasicLoader.generateSuffixes( joins + 1, collectionJoins );
StringBuffer whereString = whereString(
alias,
oneToManyPersister.getKeyColumnNames(),
subquery,
batchSize
);
String filter = oneToManyPersister.filterFragment( alias, getEnabledFilters() );
whereString.insert( 0, StringHelper.moveAndToBeginning(filter) );
JoinFragment ojf = mergeOuterJoins(associations);
Select select = new Select( getDialect() )
.setSelectClause(
oneToManyPersister.selectFragment(null, null, alias, suffixes[joins], collectionSuffixes[0], true) +
selectString(associations)
)
.setFromClause(
elementPersister.fromTableFragment(alias) +
elementPersister.fromJoinFragment(alias, true, true)
)
.setWhereClause( whereString.toString() )
.setOuterJoins(
ojf.toFromFragmentString(),
ojf.toWhereFragmentString() +
elementPersister.whereJoinFragment(alias, true, true)
);
select.setOrderByClause( orderBy( associations, oneToManyPersister.getSQLOrderByString(alias) ) );
if ( getFactory().getSettings().isCommentsEnabled() ) {
select.setComment( "load one-to-many " + oneToManyPersister.getRole() );
}
sql = select.toStatementString();
}
public Object[] getNaturalIdentifierSnapshot(Serializable id, SessionImplementor session) throws HibernateException {
if ( !hasNaturalIdentifier() ) {
throw new MappingException( "persistent class did not define a natural-id : " + MessageHelper.infoString( this ) );
}
if ( log.isTraceEnabled() ) {
log.trace( "Getting current natural-id snapshot state for: " + MessageHelper.infoString( this, id, getFactory() ) );
}
int[] naturalIdPropertyIndexes = getNaturalIdentifierProperties();
int naturalIdPropertyCount = naturalIdPropertyIndexes.length;
boolean[] naturalIdMarkers = new boolean[ getPropertySpan() ];
Type[] extractionTypes = new Type[ naturalIdPropertyCount ];
for ( int i = 0; i < naturalIdPropertyCount; i++ ) {
extractionTypes[i] = getPropertyTypes()[ naturalIdPropertyIndexes[i] ];
naturalIdMarkers[ naturalIdPropertyIndexes[i] ] = true;
}
///////////////////////////////////////////////////////////////////////
// TODO : look at perhaps caching this...
Select select = new Select( getFactory().getDialect() );
if ( getFactory().getSettings().isCommentsEnabled() ) {
select.setComment( "get current natural-id state " + getEntityName() );
}
select.setSelectClause( concretePropertySelectFragmentSansLeadingComma( getRootAlias(), naturalIdMarkers ) );
select.setFromClause( fromTableFragment( getRootAlias() ) + fromJoinFragment( getRootAlias(), true, false ) );
String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
String whereClause = new StringBuffer()
.append( StringHelper.join( "=? and ",
aliasedIdColumns ) )
.append( "=?" )
.append( whereJoinFragment( getRootAlias(), true, false ) )
.toString();
String sql = select.setOuterJoins( "", "" )
.setWhereClause( whereClause )
.toStatementString();
///////////////////////////////////////////////////////////////////////
Object[] snapshot = new Object[ naturalIdPropertyCount ];
try {
PreparedStatement ps = session.getBatcher().prepareSelectStatement( sql );
try {
getIdentifierType().nullSafeSet( ps, id, 1, session );
ResultSet rs = ps.executeQuery();
try {
//if there is no resulting row, return null
if ( !rs.next() ) {
return null;
}
for ( int i = 0; i < naturalIdPropertyCount; i++ ) {
snapshot[i] = extractionTypes[i].hydrate( rs, getPropertyAliases( "", naturalIdPropertyIndexes[i] ), session, null );
}
return snapshot;
}
finally {
rs.close();
}
}
finally {
session.getBatcher().closeStatement( ps );
}
}
catch ( SQLException sqle ) {
throw JDBCExceptionHelper.convert(
getFactory().getSQLExceptionConverter(),
sqle,
"could not retrieve snapshot: " +
MessageHelper.infoString( this, id, getFactory() ),
sql
);
}
}
protected String generateIdInsertSelect(Queryable persister, String tableAlias, AST whereClause) {
Select select = new Select( getFactory().getDialect() );
SelectFragment selectFragment = new SelectFragment()
.addColumns( tableAlias, persister.getIdentifierColumnNames(), persister.getIdentifierColumnNames() );
select.setSelectClause( selectFragment.toFragmentString().substring( 2 ) );
String rootTableName = persister.getTableName();
String fromJoinFragment = persister.fromJoinFragment( tableAlias, true, false );
String whereJoinFragment = persister.whereJoinFragment( tableAlias, true, false );
select.setFromClause( rootTableName + ' ' + tableAlias + fromJoinFragment );
if ( whereJoinFragment == null ) {
whereJoinFragment = "";
}
else {
whereJoinFragment = whereJoinFragment.trim();
if ( whereJoinFragment.startsWith( "and" ) ) {
whereJoinFragment = whereJoinFragment.substring( 4 );
}
}
String userWhereClause = "";
if ( whereClause.getNumberOfChildren() != 0 ) {
// If a where clause was specified in the update/delete query, use it to limit the
// returned ids here...
try {
SqlGenerator sqlGenerator = new SqlGenerator( getFactory() );
sqlGenerator.whereClause( whereClause );
userWhereClause = sqlGenerator.getSQL().substring( 7 ); // strip the " where "
}
catch ( RecognitionException e ) {
throw new HibernateException( "Unable to generate id select for DML operation", e );
}
if ( whereJoinFragment.length() > 0 ) {
whereJoinFragment += " and ";
}
}
select.setWhereClause( whereJoinFragment + userWhereClause );
InsertSelect insert = new InsertSelect( getFactory().getDialect() );
if ( getFactory().getSettings().isCommentsEnabled() ) {
insert.setComment( "insert-select for " + persister.getEntityName() + " ids" );
}
insert.setTableName( persister.getTemporaryIdTableName() );
insert.setSelect( select );
return insert.toStatementString();
}
public void applyFilters(Select select, String alias, Map filters) {
}