Example usage for org.hibernate.hql.internal.ast HqlSqlWalker getAssignmentSpecifications

List of usage examples for org.hibernate.hql.internal.ast HqlSqlWalker getAssignmentSpecifications

Introduction

In this page you can find the example usage for org.hibernate.hql.internal.ast HqlSqlWalker getAssignmentSpecifications.

Prototype

public ArrayList getAssignmentSpecifications() 

Source Link

Usage

From source file:com.blazebit.persistence.integration.hibernate.CustomTableBasedUpdateHandlerImpl.java

License:Apache License

public CustomTableBasedUpdateHandlerImpl(TableBasedUpdateHandlerImpl delegate, HqlSqlWalker walker) {
    this.delegate = delegate;
    // Here comes the madness...
    // We need to somehow execute our code within the temporary table scope, but since there is no way for use to do this externally,
    // we need to use invocation handlers to get a callback at the right time
    // First, we reduce the update statements
    String[] updates = delegate.getSqlStatements();
    UpdateStatement updateStatement = (UpdateStatement) walker.getAST();
    FromElement fromElement = updateStatement.getFromClause().getFromElement();
    AbstractEntityPersister targetedPersister = (AbstractEntityPersister) fromElement.getQueryable();
    String[] tableNames = targetedPersister.getConstraintOrderedTableNameClosure();
    String[][] columnNames = targetedPersister.getContraintOrderedTableKeyColumnClosure();

    int subclassCount = delegate.getTargetedQueryable().getEntityMetamodel().getSubclassEntityNames().size();
    Set<String> subclassTableNames = new HashSet<>();
    for (int i = 0; i < subclassCount; i++) {
        subclassTableNames.add(delegate.getTargetedQueryable().getSubclassTableName(i));
    }//www  . j  av  a2s  .com

    final String[] secondaryTableUpdates = updates.clone();
    final String[] secondaryTableInserts = new String[updates.length];

    StringBuilder sb = new StringBuilder();
    StringBuilder selectSb = new StringBuilder();
    String selectString = "select ";
    String inString = "IN (";
    for (int tableIndex = 0; tableIndex < tableNames.length; tableIndex++) {
        if (updates[tableIndex] != null) {
            // We introduce a dummy update statement that we react upon
            if (subclassTableNames.contains(tableNames[tableIndex])) {
                secondaryTableUpdates[tableIndex] = null;
            } else {
                sb.setLength(0);
                selectSb.setLength(0);

                boolean affected = false;
                String idSubselect = updates[tableIndex].substring(
                        updates[tableIndex].lastIndexOf(inString) + inString.length(),
                        updates[tableIndex].length() - 1);

                sb.append("insert into ").append(tableNames[tableIndex]);
                String[] keyColumnNames = columnNames[tableIndex];
                sb.append('(');

                final List<AssignmentSpecification> assignmentSpecifications = walker
                        .getAssignmentSpecifications();
                for (AssignmentSpecification assignmentSpecification : assignmentSpecifications) {
                    if (assignmentSpecification.affectsTable(tableNames[tableIndex])) {
                        String sqlAssignmentFragment = assignmentSpecification.getSqlAssignmentFragment();
                        int eqIndex = sqlAssignmentFragment.indexOf('=');
                        sb.append(sqlAssignmentFragment, 0, eqIndex);
                        sb.append(',');
                        selectSb.append(sqlAssignmentFragment, eqIndex + 1, sqlAssignmentFragment.length());
                        selectSb.append(',');

                        affected = true;
                    }
                }
                if (affected) {
                    for (int i = 0; i < keyColumnNames.length; i++) {
                        sb.append(keyColumnNames[i]);
                        sb.append(',');
                    }
                    sb.setCharAt(sb.length() - 1, ')');
                    sb.append(' ').append(selectString);
                    sb.append(selectSb);
                    sb.append(idSubselect, selectString.length(), idSubselect.length());
                    sb.append(" where not exists (select 1 from ");
                    sb.append(tableNames[tableIndex]);
                    sb.append(" a where ");

                    for (int i = 0; i < keyColumnNames.length; i++) {
                        sb.append("a.");
                        sb.append(keyColumnNames[i]);
                        sb.append(" = ");
                        sb.append(keyColumnNames[i]);
                        sb.append(" and ");
                    }

                    sb.setLength(sb.length() - " and ".length());
                    sb.append(")");

                    secondaryTableInserts[tableIndex] = sb.toString();
                }

                updates[tableIndex] = "";
            }
        }
    }

    this.secondaryTableUpdates = secondaryTableUpdates;
    this.secondaryTableInserts = secondaryTableInserts;
}