下面列出了怎么用org.hibernate.persister.collection.AbstractCollectionPersister的API类实例代码及写法,或者点击链接到github查看源代码。
public void cleanTables() {
doInJPA(this::sessionFactory, entityManager -> {
((MetamodelImpl) entityManager.getMetamodel()).collectionPersisters()
.values()
.forEach(x -> {
String deleteQuery = getDeleteQuery(((AbstractCollectionPersister) x).getTableName());
entityManager.createNativeQuery(deleteQuery).executeUpdate();
});
Arrays.stream(getAnnotatedClasses())
.filter(entity -> entity.getAnnotation(Subselect.class) == null)
.forEach(x -> {
String name = x.getAnnotation(Entity.class).name();
if (name == null || name.isEmpty()) {
name = x.getSimpleName();
}
entityManager.createQuery(getDeleteQuery(name)).executeUpdate();
});
});
}
public CteValuesListDeleteHandlerImpl(
SessionFactoryImplementor factory,
HqlSqlWalker walker,
String catalog,
String schema) {
super( factory, walker, catalog, schema );
final String idSubselect = generateIdSubselect( getTargetedQueryable() );
for ( Type type : getTargetedQueryable().getPropertyTypes() ) {
if ( type.isCollectionType() ) {
CollectionType cType = (CollectionType) type;
AbstractCollectionPersister cPersister = (AbstractCollectionPersister) factory.getMetamodel().collectionPersister( cType.getRole() );
if ( cPersister.isManyToMany() ) {
deletes.add( generateDelete(
cPersister.getTableName(),
cPersister.getKeyColumnNames(),
idSubselect,
"bulk delete - m2m join table cleanup"
) );
}
}
}
String[] tableNames = getTargetedQueryable().getConstraintOrderedTableNameClosure();
String[][] columnNames = getTargetedQueryable().getContraintOrderedTableKeyColumnClosure();
for ( int i = 0; i < tableNames.length; i++ ) {
// TODO : an optimization here would be to consider cascade deletes and not gen those delete statements;
// the difficulty is the ordering of the tables here vs the cascade attributes on the persisters ->
// the table info gotten here should really be self-contained (i.e., a class representation
// defining all the needed attributes), then we could then get an array of those
deletes.add( generateDelete( tableNames[i], columnNames[i], idSubselect, "bulk delete" ) );
}
}
public TableBasedDeleteHandlerImpl(
SessionFactoryImplementor factory,
HqlSqlWalker walker,
IdTableInfo idTableInfo) {
super( factory, walker );
DeleteStatement deleteStatement = ( DeleteStatement ) walker.getAST();
FromElement fromElement = deleteStatement.getFromClause().getFromElement();
this.targetedPersister = fromElement.getQueryable();
final String bulkTargetAlias = fromElement.getTableAlias();
final ProcessedWhereClause processedWhereClause = processWhereClause( deleteStatement.getWhereClause() );
this.idSelectParameterSpecifications = processedWhereClause.getIdSelectParameterSpecifications();
this.idInsertSelect = generateIdInsertSelect( bulkTargetAlias, idTableInfo, processedWhereClause );
log.tracev( "Generated ID-INSERT-SELECT SQL (multi-table delete) : {0}", idInsertSelect );
final String idSubselect = generateIdSubselect( targetedPersister, idTableInfo );
deletes = new ArrayList<>();
// If many-to-many, delete the FK row in the collection table.
// This partially overlaps with DeleteExecutor, but it instead uses the temp table in the idSubselect.
for ( Type type : targetedPersister.getPropertyTypes() ) {
if ( type.isCollectionType() ) {
CollectionType cType = (CollectionType) type;
AbstractCollectionPersister cPersister = (AbstractCollectionPersister) factory.getMetamodel().collectionPersister( cType.getRole() );
if ( cPersister.isManyToMany() ) {
deletes.add( generateDelete( cPersister.getTableName(),
cPersister.getKeyColumnNames(), idSubselect, "bulk delete - m2m join table cleanup"));
}
}
}
String[] tableNames = targetedPersister.getConstraintOrderedTableNameClosure();
String[][] columnNames = targetedPersister.getContraintOrderedTableKeyColumnClosure();
for ( int i = 0; i < tableNames.length; i++ ) {
// TODO : an optimization here would be to consider cascade deletes and not gen those delete statements;
// the difficulty is the ordering of the tables here vs the cascade attributes on the persisters ->
// the table info gotten here should really be self-contained (i.e., a class representation
// defining all the needed attributes), then we could then get an array of those
deletes.add( generateDelete( tableNames[i], columnNames[i], idSubselect, "bulk delete"));
}
}
@Override
public int execute(
SharedSessionContractImplementor session,
QueryParameters queryParameters) {
IdsClauseBuilder values = prepareInlineStatement( session, queryParameters );
if ( !values.getIds().isEmpty() ) {
final String idSubselect = values.toStatement();
for ( Type type : getTargetedQueryable().getPropertyTypes() ) {
if ( type.isCollectionType() ) {
CollectionType cType = (CollectionType) type;
AbstractCollectionPersister cPersister = (AbstractCollectionPersister) factory().getMetamodel().collectionPersister( cType.getRole() );
if ( cPersister.isManyToMany() ) {
deletes.add( generateDelete(
cPersister.getTableName(),
cPersister.getKeyColumnNames(),
idSubselect,
"bulk delete - m2m join table cleanup"
).toStatementString() );
}
}
}
String[] tableNames = getTargetedQueryable().getConstraintOrderedTableNameClosure();
String[][] columnNames = getTargetedQueryable().getContraintOrderedTableKeyColumnClosure();
for ( int i = 0; i < tableNames.length; i++ ) {
// TODO : an optimization here would be to consider cascade deletes and not gen those delete statements;
// the difficulty is the ordering of the tables here vs the cascade attributes on the persisters ->
// the table info gotten here should really be self-contained (i.e., a class representation
// defining all the needed attributes), then we could then get an array of those
deletes.add( generateDelete( tableNames[i], columnNames[i], idSubselect, "bulk delete" ).toStatementString() );
}
// Start performing the deletes
for ( String delete : deletes ) {
if ( delete == null) {
continue;
}
try {
try ( PreparedStatement ps = session
.getJdbcCoordinator().getStatementPreparer()
.prepareStatement( delete, false ) ) {
session
.getJdbcCoordinator().getResultSetReturn()
.executeUpdate( ps );
}
}
catch ( SQLException e ) {
throw convert( e, "error performing bulk delete", delete );
}
}
}
return values.getIds().size();
}
public DeleteExecutor(HqlSqlWalker walker, Queryable persister) {
super( walker, persister );
final SessionFactoryImplementor factory = walker.getSessionFactoryHelper().getFactory();
final Dialect dialect = factory.getJdbcServices().getJdbcEnvironment().getDialect();
try {
final DeleteStatement deleteStatement = (DeleteStatement) walker.getAST();
final String idSubselectWhere;
if ( deleteStatement.hasWhereClause() ) {
final AST whereClause = deleteStatement.getWhereClause();
final SqlGenerator gen = new SqlGenerator( factory );
gen.whereClause( whereClause );
parameterSpecifications = gen.getCollectedParameters();
idSubselectWhere = gen.getSQL().length() > 7 ? gen.getSQL() : "";
}
else {
parameterSpecifications = new ArrayList<>();
idSubselectWhere = "";
}
// If many-to-many, delete the FK row in the collection table.
for ( Type type : persister.getPropertyTypes() ) {
if ( type.isCollectionType() ) {
final CollectionType cType = (CollectionType) type;
final AbstractCollectionPersister cPersister = (AbstractCollectionPersister) factory.getMetamodel().collectionPersister( cType.getRole() );
if ( cPersister.isManyToMany() ) {
if ( persister.getIdentifierColumnNames().length > 1
&& !dialect.supportsTuplesInSubqueries() ) {
LOG.warn(
"This dialect is unable to cascade the delete into the many-to-many join table" +
" when the entity has multiple primary keys. Either properly setup cascading on" +
" the constraints or manually clear the associations prior to deleting the entities."
);
}
else {
final String idSubselect = "(select "
+ String.join( ", ", persister.getIdentifierColumnNames() ) + " from "
+ persister.getTableName() + idSubselectWhere + ")";
final String where = "(" + String.join( ", ", cPersister.getKeyColumnNames() )
+ ") in " + idSubselect;
final Delete delete = new Delete().setTableName( cPersister.getTableName() ).setWhere( where );
if ( factory.getSessionFactoryOptions().isCommentsEnabled() ) {
delete.setComment( "delete FKs in join table" );
}
deletes.add( delete.toStatementString() );
}
}
}
}
}
catch (RecognitionException e) {
throw new HibernateException( "Unable to delete the FKs in the join table!", e );
}
}
@Override
public int execute(
SharedSessionContractImplementor session,
QueryParameters queryParameters) {
IdsClauseBuilder values = prepareInlineStatement( session, queryParameters );
List<String> currentDeletes = new ArrayList<>();
if ( !values.getIds().isEmpty() ) {
final String idSubselect = values.toStatement();
for ( Type type : getTargetedQueryable().getPropertyTypes() ) {
if ( type.isCollectionType() ) {
CollectionType cType = (CollectionType) type;
AbstractCollectionPersister cPersister = (AbstractCollectionPersister) factory().getMetamodel().collectionPersister( cType.getRole() );
if ( cPersister.isManyToMany() ) {
currentDeletes.add( generateDelete(
cPersister.getTableName(),
cPersister.getKeyColumnNames(),
idSubselect,
"bulk delete - m2m join table cleanup"
).toStatementString() );
}
}
}
String[] tableNames = getTargetedQueryable().getConstraintOrderedTableNameClosure();
String[][] columnNames = getTargetedQueryable().getContraintOrderedTableKeyColumnClosure();
for ( int i = 0; i < tableNames.length; i++ ) {
// TODO : an optimization here would be to consider cascade deletes and not gen those delete statements;
// the difficulty is the ordering of the tables here vs the cascade attributes on the persisters ->
// the table info gotten here should really be self-contained (i.e., a class representation
// defining all the needed attributes), then we could then get an array of those
currentDeletes.add( generateDelete( tableNames[i], columnNames[i], idSubselect, "bulk delete" ).toStatementString() );
}
// Start performing the deletes
for ( String delete : currentDeletes ) {
if ( delete == null) {
continue;
}
try {
try ( PreparedStatement ps = session
.getJdbcCoordinator().getStatementPreparer()
.prepareStatement( delete, false ) ) {
session
.getJdbcCoordinator().getResultSetReturn()
.executeUpdate( ps );
}
}
catch ( SQLException e ) {
throw convert( e, "error performing bulk delete", delete );
}
}
//deletes.addAll( currentDeletes );
}
return values.getIds().size();
}