Example usage for org.hibernate.hql.internal.ast.tree FromElement getQueryable

List of usage examples for org.hibernate.hql.internal.ast.tree FromElement getQueryable

Introduction

In this page you can find the example usage for org.hibernate.hql.internal.ast.tree FromElement getQueryable.

Prototype

public Queryable getQueryable() 

Source Link

Usage

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

License:Apache License

@Override
public UpdateHandler buildUpdateHandler(SessionFactoryImplementor factory, HqlSqlWalker walker) {
    UpdateHandler updateHandler = delegate.buildUpdateHandler(factory, walker);

    final UpdateStatement updateStatement = (UpdateStatement) walker.getAST();
    final FromElement fromElement = updateStatement.getFromClause().getFromElement();
    final AbstractEntityPersister targetedPersister = (AbstractEntityPersister) fromElement.getQueryable();

    // Only do this when we have secondary tables
    if (targetedPersister.getConstraintOrderedTableNameClosure().length > 1) {
        if (updateHandler instanceof TableBasedUpdateHandlerImpl) {
            return new CustomTableBasedUpdateHandlerImpl((TableBasedUpdateHandlerImpl) updateHandler, walker);
        } else {/*from  w ww  .java2 s.  com*/
            LOG.warning(
                    "Unsupported update handler that can't be adapted to support updates to secondary tables: "
                            + updateHandler);
        }
    }

    return updateHandler;
}

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));
    }/*from  w  w w . j a  v a 2s.  c om*/

    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;
}