Ejemplo n.º 1
0
  /**
   * Method to create a PreparedStatement for use with the query.
   *
   * @param conn the Connection
   * @param queryStmt The statement text for the query
   * @param query The query
   * @return the PreparedStatement
   * @throws SQLException Thrown if an error occurs creating the statement
   */
  public static PreparedStatement getPreparedStatementForQuery(
      ManagedConnection conn, String queryStmt, Query query) throws SQLException {
    // Apply any non-standard result set definition if required (either from the PMF, or via query
    // extensions)
    String rsTypeString = RDBMSQueryUtils.getResultSetTypeForQuery(query);
    if (rsTypeString != null
        && (!rsTypeString.equals("scroll-sensitive")
            && !rsTypeString.equals("forward-only")
            && !rsTypeString.equals("scroll-insensitive"))) {
      throw new NucleusUserException(LOCALISER.msg("052510"));
    }
    if (rsTypeString != null) {
      DatastoreAdapter dba = ((RDBMSStoreManager) query.getStoreManager()).getDatastoreAdapter();

      // Add checks on what the DatastoreAdapter supports
      if (rsTypeString.equals("scroll-sensitive")
          && !dba.supportsOption(DatastoreAdapter.RESULTSET_TYPE_SCROLL_SENSITIVE)) {
        NucleusLogger.DATASTORE_RETRIEVE.info(
            "Query requested to run with result-set type of "
                + rsTypeString
                + " yet not supported by adapter. Using forward-only");
        rsTypeString = "forward-only";
      } else if (rsTypeString.equals("scroll-insensitive")
          && !dba.supportsOption(DatastoreAdapter.RESULTSET_TYPE_SCROLL_INSENSITIVE)) {
        NucleusLogger.DATASTORE_RETRIEVE.info(
            "Query requested to run with result-set type of "
                + rsTypeString
                + " yet not supported by adapter. Using forward-only");
        rsTypeString = "forward-only";
      } else if (rsTypeString.equals("forward-only")
          && !dba.supportsOption(DatastoreAdapter.RESULTSET_TYPE_FORWARD_ONLY)) {
        NucleusLogger.DATASTORE_RETRIEVE.info(
            "Query requested to run with result-set type of "
                + rsTypeString
                + " yet not supported by adapter. Using scroll-sensitive");
        rsTypeString = "scroll-sensitive";
      }
    }

    String rsConcurrencyString = RDBMSQueryUtils.getResultSetConcurrencyForQuery(query);
    if (rsConcurrencyString != null
        && (!rsConcurrencyString.equals("read-only")
            && !rsConcurrencyString.equals("updateable"))) {
      throw new NucleusUserException(LOCALISER.msg("052511"));
    }

    SQLController sqlControl = ((RDBMSStoreManager) query.getStoreManager()).getSQLController();
    PreparedStatement ps =
        sqlControl.getStatementForQuery(conn, queryStmt, rsTypeString, rsConcurrencyString);

    return ps;
  }
Ejemplo n.º 2
0
 /**
  * Convenience logging method to output the mapping information for an element, key, value field
  *
  * @param mapping The mapping
  */
 protected void debugMapping(JavaTypeMapping mapping) {
   if (NucleusLogger.DATASTORE.isDebugEnabled()) {
     // Provide field->column mapping debug message
     StringBuffer columnsStr = new StringBuffer();
     for (int i = 0; i < mapping.getNumberOfDatastoreMappings(); i++) {
       if (i > 0) {
         columnsStr.append(",");
       }
       columnsStr.append(mapping.getDatastoreMapping(i).getDatastoreField());
     }
     if (mapping.getNumberOfDatastoreMappings() == 0) {
       columnsStr.append("[none]");
     }
     StringBuffer datastoreMappingTypes = new StringBuffer();
     for (int i = 0; i < mapping.getNumberOfDatastoreMappings(); i++) {
       if (i > 0) {
         datastoreMappingTypes.append(',');
       }
       datastoreMappingTypes.append(mapping.getDatastoreMapping(i).getClass().getName());
     }
     NucleusLogger.DATASTORE.debug(
         LOCALISER.msg(
             "057010",
             mmd.getFullFieldName(),
             columnsStr.toString(),
             mapping.getClass().getName(),
             datastoreMappingTypes.toString()));
   }
 }
Ejemplo n.º 3
0
 public VersionMetaData setStrategy(String strategy) {
   if (StringUtils.isWhitespace(strategy)
       || VersionStrategy.getVersionStrategy(strategy) == null) {
     throw new RuntimeException(LOCALISER.msg("044156"));
   }
   this.versionStrategy = VersionStrategy.getVersionStrategy(strategy);
   return this;
 }
  /* (non-Javadoc)
   * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
   */
  public SQLExpression getExpression(SQLExpression expr, List args) {
    if (expr != null) {
      throw new NucleusException(LOCALISER.msg("060002", getFunctionName(), expr));
    } else if (args == null || args.size() != 1) {
      throw new NucleusException(getFunctionName() + " is only supported with a single argument");
    }

    if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.RESULT
        || stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.HAVING) {
      // FUNC(argExpr)
      JavaTypeMapping m = null;
      if (args.get(0) instanceof SQLExpression) {
        // Use same java type as the argument
        SQLExpression argExpr = (SQLExpression) args.get(0);
        m = getMappingForClass(argExpr.getJavaTypeMapping().getJavaType());
        if (args.get(0) instanceof TemporalExpression) {
          return new AggregateTemporalExpression(stmt, m, getFunctionName(), args);
        } else {
          return new AggregateNumericExpression(stmt, m, getFunctionName(), args);
        }
      } else {
        // What is coming through here?
        // Fallback to the type for this aggregate TODO Allow for temporal types
        m = getMappingForClass(double.class);
        return new AggregateNumericExpression(stmt, m, getFunctionName(), args);
      }
    } else {
      // Handle as Subquery "SELECT AVG(expr) FROM tbl"
      SQLExpression argExpr = (SQLExpression) args.get(0);
      SQLStatement subStmt =
          new SQLStatement(
              stmt,
              stmt.getRDBMSManager(),
              argExpr.getSQLTable().getTable(),
              argExpr.getSQLTable().getAlias(),
              null);
      subStmt.setClassLoaderResolver(clr);

      JavaTypeMapping mapping =
          stmt.getRDBMSManager()
              .getMappingManager()
              .getMappingWithDatastoreMapping(String.class, false, false, clr);
      String aggregateString = getFunctionName() + "(" + argExpr.toSQLText() + ")";
      SQLExpression aggExpr = exprFactory.newLiteral(subStmt, mapping, aggregateString);
      ((StringLiteral) aggExpr).generateStatementWithoutQuotes();
      subStmt.select(aggExpr, null);

      JavaTypeMapping subqMapping = exprFactory.getMappingForType(Integer.class, false);
      SQLExpression subqExpr = null;
      if (argExpr instanceof TemporalExpression) {
        subqExpr = new TemporalSubqueryExpression(stmt, subStmt);
      } else {
        subqExpr = new NumericSubqueryExpression(stmt, subStmt);
      }
      subqExpr.setJavaTypeMapping(subqMapping);
      return subqExpr;
    }
  }
Ejemplo n.º 5
0
  /* (non-Javadoc)
   * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
   */
  public SQLExpression getExpression(SQLExpression expr, List args) {
    if (!(expr instanceof TemporalExpression)) {
      throw new NucleusException(LOCALISER.msg("060001", "getSecond()", expr));
    }

    ArrayList funcArgs = new ArrayList();
    funcArgs.add(expr);
    return new NumericExpression(stmt, getMappingForClass(int.class), "SECOND", funcArgs);
  }
Ejemplo n.º 6
0
  /**
   * Method to apply any restrictions to the created ResultSet.
   *
   * @param ps The PreparedStatement
   * @param query The query
   * @param applyTimeout Whether to apply the query timeout (if any) direct to the PreparedStatement
   * @throws SQLException Thrown when an error occurs applying the constraints
   */
  public static void prepareStatementForExecution(
      PreparedStatement ps, Query query, boolean applyTimeout) throws SQLException {
    NucleusContext nucleusCtx = query.getExecutionContext().getNucleusContext();
    RDBMSStoreManager storeMgr = (RDBMSStoreManager) query.getStoreManager();
    PersistenceConfiguration conf = nucleusCtx.getPersistenceConfiguration();

    if (applyTimeout) {
      Integer timeout = query.getDatastoreReadTimeoutMillis();
      if (timeout != null && timeout > 0) {
        ps.setQueryTimeout(timeout / 1000);
      }
    }

    // Apply any fetch size
    int fetchSize = 0;
    if (query.getFetchPlan().getFetchSize() > 0) {
      // FetchPlan has a size set so use that
      fetchSize = query.getFetchPlan().getFetchSize();
    }
    if (storeMgr.getDatastoreAdapter().supportsQueryFetchSize(fetchSize)) {
      ps.setFetchSize(fetchSize);
    }

    // Apply any fetch direction
    String fetchDir =
        conf.getStringProperty(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_FETCH_DIRECTION);
    Object fetchDirExt =
        query.getExtension(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_FETCH_DIRECTION);
    if (fetchDirExt != null) {
      fetchDir = (String) fetchDirExt;
      if (!fetchDir.equals("forward")
          && !fetchDir.equals("reverse")
          && !fetchDir.equals("unknown")) {
        throw new NucleusUserException(LOCALISER.msg("052512"));
      }
    }

    if (fetchDir.equals("reverse")) {
      ps.setFetchDirection(ResultSet.FETCH_REVERSE);
    } else if (fetchDir.equals("unknown")) {
      ps.setFetchDirection(ResultSet.FETCH_UNKNOWN);
    }

    // Add a limit on the number of rows to include the maximum we may need
    long toExclNo = query.getRangeToExcl();
    if (toExclNo != 0 && toExclNo != Long.MAX_VALUE) {
      if (toExclNo > Integer.MAX_VALUE) {
        // setMaxRows takes an int as input so limit to the correct range
        ps.setMaxRows(Integer.MAX_VALUE);
      } else {
        ps.setMaxRows((int) toExclNo);
      }
    }
  }
Ejemplo n.º 7
0
  /**
   * Constructor.
   *
   * @param tableName The Table SQL identifier
   * @param mmd Field meta data for the owner field/property
   * @param storeMgr Manager for the datastore.
   */
  protected JoinTable(
      DatastoreIdentifier tableName, AbstractMemberMetaData mmd, RDBMSStoreManager storeMgr) {
    super(tableName, storeMgr);

    this.mmd = mmd;
    this.ownerType = mmd.getClassName(true);

    if (mmd.getPersistenceModifier() == FieldPersistenceModifier.NONE) {
      throw new NucleusException(LOCALISER.msg("057006", mmd.getName())).setFatal();
    }
  }
Ejemplo n.º 8
0
  /**
   * Method to add an element to the TreeSet.
   *
   * @param element The new element
   * @return Whether it was added ok.
   */
  public boolean add(Object element) {
    // Reject inappropriate elements
    if (!allowNulls && element == null) {
      throw new NullPointerException(
          "Nulls not allowed for collection at field "
              + ownerMmd.getName()
              + " but element is null");
    }

    if (useCache) {
      loadFromStore();
    }
    if (contains(element)) {
      return false;
    }

    if (ownerOP != null && ownerOP.getExecutionContext().getManageRelations()) {
      // Relationship management
      ownerOP
          .getExecutionContext()
          .getRelationshipManager(ownerOP)
          .relationAdd(ownerMmd.getAbsoluteFieldNumber(), element);
    }

    boolean backingSuccess = true;
    if (backingStore != null) {
      if (SCOUtils.useQueuedUpdate(queued, ownerOP)) {
        ownerOP
            .getExecutionContext()
            .addOperationToQueue(new CollectionAddOperation(ownerOP, backingStore, element));
      } else {
        try {
          backingStore.add(ownerOP, element, (useCache ? delegate.size() : -1));
        } catch (NucleusDataStoreException dse) {
          NucleusLogger.PERSISTENCE.warn(LOCALISER.msg("023013", "add", ownerMmd.getName(), dse));
          backingSuccess = false;
        }
      }
    }

    // Only make it dirty after adding the field to the datastore so we give it time
    // to be inserted - otherwise jdoPreStore on this object would have been called before
    // completing the addition
    makeDirty();

    boolean delegateSuccess = delegate.add(element);

    if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) {
      ownerOP.getExecutionContext().processNontransactionalUpdate();
    }
    return (backingStore != null ? backingSuccess : delegateSuccess);
  }
Ejemplo n.º 9
0
  /**
   * Convenience method to apply the user specification of <primary-key> columns
   *
   * @param pkmd MetaData for the primary key
   */
  protected void applyUserPrimaryKeySpecification(PrimaryKeyMetaData pkmd) {
    ColumnMetaData[] pkCols = pkmd.getColumnMetaData();
    for (int i = 0; i < pkCols.length; i++) {
      String colName = pkCols[i].getName();
      boolean found = false;
      for (int j = 0; j < ownerMapping.getNumberOfDatastoreMappings(); j++) {
        if (ownerMapping
            .getDatastoreMapping(j)
            .getDatastoreField()
            .getIdentifier()
            .getIdentifierName()
            .equals(colName)) {
          ownerMapping.getDatastoreMapping(j).getDatastoreField().setAsPrimaryKey();
          found = true;
        }
      }

      if (!found) {
        for (int j = 0; j < keyMapping.getNumberOfDatastoreMappings(); j++) {
          if (keyMapping
              .getDatastoreMapping(j)
              .getDatastoreField()
              .getIdentifier()
              .getIdentifierName()
              .equals(colName)) {
            keyMapping.getDatastoreMapping(j).getDatastoreField().setAsPrimaryKey();
            found = true;
          }
        }
      }

      if (!found) {
        for (int j = 0; j < valueMapping.getNumberOfDatastoreMappings(); j++) {
          if (valueMapping
              .getDatastoreMapping(j)
              .getDatastoreField()
              .getIdentifier()
              .getIdentifierName()
              .equals(colName)) {
            valueMapping.getDatastoreMapping(j).getDatastoreField().setAsPrimaryKey();
            found = true;
          }
        }
      }

      if (!found) {
        throw new NucleusUserException(LOCALISER.msg("057040", toString(), colName));
      }
    }
  }
Ejemplo n.º 10
0
  /** Method to load all elements from the "backing store" where appropriate. */
  protected void loadFromStore() {
    if (backingStore != null && !isCacheLoaded) {
      if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
        NucleusLogger.PERSISTENCE.debug(
            LOCALISER.msg("023006", ownerOP.getObjectAsPrintable(), ownerMmd.getName()));
      }
      delegate.clear();
      Iterator iter = backingStore.iterator(ownerOP);
      while (iter.hasNext()) {
        delegate.add(iter.next());
      }

      isCacheLoaded = true;
    }
  }
Ejemplo n.º 11
0
  /**
   * Method to remove an element from the collection, and observe the flag for whether to allow
   * cascade delete.
   *
   * @param element The element
   * @param allowCascadeDelete Whether to allow cascade delete
   */
  public boolean remove(Object element, boolean allowCascadeDelete) {
    makeDirty();

    if (useCache) {
      loadFromStore();
    }

    int size = (useCache ? delegate.size() : -1);
    boolean contained = delegate.contains(element);
    boolean delegateSuccess = delegate.remove(element);
    if (ownerOP != null && ownerOP.getExecutionContext().getManageRelations()) {
      ownerOP
          .getExecutionContext()
          .getRelationshipManager(ownerOP)
          .relationRemove(ownerMmd.getAbsoluteFieldNumber(), element);
    }

    boolean backingSuccess = true;
    if (backingStore != null) {
      if (SCOUtils.useQueuedUpdate(queued, ownerOP)) {
        backingSuccess = contained;
        if (backingSuccess) {
          ownerOP
              .getExecutionContext()
              .addOperationToQueue(
                  new CollectionRemoveOperation(
                      ownerOP, backingStore, element, allowCascadeDelete));
        }
      } else {
        try {
          backingSuccess = backingStore.remove(ownerOP, element, size, allowCascadeDelete);
        } catch (NucleusDataStoreException dse) {
          NucleusLogger.PERSISTENCE.warn(
              LOCALISER.msg("023013", "remove", ownerMmd.getName(), dse));
          backingSuccess = false;
        }
      }
    }

    if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) {
      ownerOP.getExecutionContext().processNontransactionalUpdate();
    }

    return (backingStore != null ? backingSuccess : delegateSuccess);
  }
Ejemplo n.º 12
0
  /**
   * Method to add a collection to the TreeSet.
   *
   * @param elements The collection
   * @return Whether it was added ok.
   */
  public boolean addAll(Collection elements) {
    if (useCache) {
      loadFromStore();
    }
    if (ownerOP != null && ownerOP.getExecutionContext().getManageRelations()) {
      // Relationship management
      Iterator iter = elements.iterator();
      RelationshipManager relMgr = ownerOP.getExecutionContext().getRelationshipManager(ownerOP);
      while (iter.hasNext()) {
        relMgr.relationAdd(ownerMmd.getAbsoluteFieldNumber(), iter.next());
      }
    }

    boolean backingSuccess = true;
    if (backingStore != null) {
      if (SCOUtils.useQueuedUpdate(queued, ownerOP)) {
        for (Object element : elements) {
          ownerOP
              .getExecutionContext()
              .addOperationToQueue(new CollectionAddOperation(ownerOP, backingStore, element));
        }
      } else {
        try {
          backingSuccess =
              backingStore.addAll(ownerOP, elements, (useCache ? delegate.size() : -1));
        } catch (NucleusDataStoreException dse) {
          NucleusLogger.PERSISTENCE.warn(
              LOCALISER.msg("023013", "addAll", ownerMmd.getName(), dse));
          backingSuccess = false;
        }
      }
    }

    // Only make it dirty after adding the field to the datastore so we give it time
    // to be inserted - otherwise jdoPreStore on this object would have been called before
    // completing the addition
    makeDirty();

    boolean delegateSuccess = delegate.addAll(elements);

    if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) {
      ownerOP.getExecutionContext().processNontransactionalUpdate();
    }
    return (backingStore != null ? backingSuccess : delegateSuccess);
  }
Ejemplo n.º 13
0
  /**
   * Method to create the repository for ids to be stored.
   *
   * @return Whether it was created successfully.
   */
  protected boolean createRepository() {
    RDBMSStoreManager srm = (RDBMSStoreManager) storeMgr;
    if (!srm.isAutoCreateTables()) {
      throw new NucleusUserException(LOCALISER.msg("040011", sequenceTable));
    }

    try {
      if (sequenceTable == null) {
        initialiseSequenceTable();
      }
      sequenceTable.exists((Connection) connection.getConnection(), true);
      repositoryExists = true;
      return true;
    } catch (SQLException sqle) {
      throw new ValueGenerationException(
          "Exception thrown calling table.exists() for " + sequenceTable, sqle);
    }
  }
  public BitSet toMemberType(String str) {
    if (str == null) {
      return null;
    }

    BitSet set = new BitSet();
    StringTokenizer tokeniser = new StringTokenizer(str.substring(1, str.length() - 1), ",");
    while (tokeniser.hasMoreTokens()) {
      String token = tokeniser.nextToken().trim();
      try {
        int position = new Integer(token).intValue();
        set.set(position);
      } catch (NumberFormatException nfe) {
        throw new NucleusDataStoreException(
            LOCALISER.msg("016002", str, BitSet.class.getName()), nfe);
      }
    }
    return set;
  }
Ejemplo n.º 15
0
  /**
   * Method to reserve a block of "size" identities.
   *
   * @param size Block size
   * @return The reserved block
   */
  public ValueGenerationBlock reserveBlock(long size) {
    if (size < 1) {
      return null;
    }

    // search for an ID in the database
    List oid = new ArrayList();
    try {
      if (sequenceTable == null) {
        initialiseSequenceTable();
      }

      DatastoreIdentifier sourceTableIdentifier = null;
      if (properties.getProperty("table-name") != null) {
        sourceTableIdentifier =
            ((RDBMSStoreManager) storeMgr)
                .getIdentifierFactory()
                .newTableIdentifier(properties.getProperty("table-name"));
        // TODO Apply passed in catalog/schema to this identifier rather than the default for the
        // factory
      }
      Long nextId =
          sequenceTable.getNextVal(
              sequenceName,
              connection,
              (int) size,
              sourceTableIdentifier,
              properties.getProperty("column-name"),
              initialValue);
      for (int i = 0; i < size; i++) {
        oid.add(nextId);
        nextId = Long.valueOf(nextId.longValue() + 1);
      }
      if (NucleusLogger.VALUEGENERATION.isDebugEnabled()) {
        NucleusLogger.VALUEGENERATION.debug(LOCALISER.msg("040004", "" + size));
      }
      return new ValueGenerationBlock(oid);
    } catch (SQLException e) {
      throw new ValueGenerationException(LOCALISER_RDBMS.msg("061001", e.getMessage()));
    }
  }
Ejemplo n.º 16
0
  /**
   * Constructor.
   *
   * @param name Symbolic name for this generator
   * @param props Properties defining the behaviour of this generator
   */
  public TableGenerator(String name, Properties props) {
    super(name, props);
    allocationSize = 5;
    initialValue = -1; // So we know if being set
    if (properties != null) {
      if (properties.get("key-cache-size") != null) {
        try {
          allocationSize = Integer.parseInt(properties.getProperty("key-cache-size"));
        } catch (Exception e) {
          throw new ValueGenerationException(
              LOCALISER.msg("Sequence040006", properties.get("key-cache-size")));
        }
      }
      if (properties.get("key-initial-value") != null) {
        try {
          initialValue = Integer.parseInt(properties.getProperty("key-initial-value"));
        } catch (NumberFormatException nfe) {
          // Not an integer so ignore it
        }
      }

      if (properties.getProperty("sequence-name") != null) {
        // Specified sequence-name so use that
        sequenceName = properties.getProperty("sequence-name");
      } else if (properties.getProperty("sequence-table-basis") != null
          && properties.getProperty("sequence-table-basis").equalsIgnoreCase("table")) {
        // Use table name in the sequence table as the sequence name
        sequenceName = properties.getProperty("table-name");
      } else {
        // Use root class name (for this inheritance tree) in the sequence table as the sequence
        // name
        sequenceName = properties.getProperty("root-class-name");
      }
    } else {
      // User hasn't provided any sequence name!!!
      sequenceName = "SEQUENCENAME";
    }
  }
Ejemplo n.º 17
0
  /**
   * Method to populate any defaults, and check the validity of the MetaData.
   *
   * @param clr ClassLoaderResolver to use for any loading operations
   * @param primary the primary ClassLoader to use (or null)
   * @param mmgr MetaData manager
   */
  public void populate(ClassLoaderResolver clr, ClassLoader primary, MetaDataManager mmgr) {
    AbstractMemberMetaData mmd = (AbstractMemberMetaData) parent;
    if (!StringUtils.isWhitespace(element.type) && element.type.indexOf(',') > 0) {
      throw new InvalidMetaDataException(LOCALISER, "044131", mmd.getName(), mmd.getClassName());
    }

    // Make sure the type in "element" is set
    element.populate(
        ((AbstractMemberMetaData) parent).getAbstractClassMetaData().getPackageName(),
        clr,
        primary,
        mmgr);

    // Check the field type and see if it is castable to a Collection
    Class field_type = getMemberMetaData().getType();
    if (!java.util.Collection.class.isAssignableFrom(field_type)) {
      throw new InvalidMetaDataException(
          LOCALISER, "044132", getFieldName(), getMemberMetaData().getClassName(false));
    }

    // "element-type"
    if (element.type == null) {
      throw new InvalidMetaDataException(
          LOCALISER, "044133", getFieldName(), getMemberMetaData().getClassName(false));
    }

    // Check that the element type exists
    Class elementTypeClass = null;
    try {
      elementTypeClass = clr.classForName(element.type, primary);
    } catch (ClassNotResolvedException cnre) {
      throw new InvalidMetaDataException(
          LOCALISER,
          "044134",
          getFieldName(),
          getMemberMetaData().getClassName(false),
          element.type);
    }

    if (!elementTypeClass.getName().equals(element.type)) {
      // The element-type has been resolved from what was specified in the MetaData - update to the
      // fully-qualified name
      NucleusLogger.METADATA.info(
          LOCALISER.msg(
              "044135",
              getFieldName(),
              getMemberMetaData().getClassName(false),
              element.type,
              elementTypeClass.getName()));
      element.type = elementTypeClass.getName();
    }

    // "embedded-element"
    ApiAdapter api = mmgr.getApiAdapter();
    if (element.embedded == null) {
      // Assign default for "embedded-element" based on 18.13.1 of JDO 2 spec
      // Note : this fails when using in the enhancer since not yet PC
      if (mmgr.getNucleusContext().getTypeManager().isDefaultEmbeddedType(elementTypeClass)) {
        element.embedded = Boolean.TRUE;
      } else if (api.isPersistable(elementTypeClass)
          || Object.class.isAssignableFrom(elementTypeClass)
          || elementTypeClass.isInterface()) {
        element.embedded = Boolean.FALSE;
      } else {
        element.embedded = Boolean.TRUE;
      }
    }
    if (Boolean.FALSE.equals(element.embedded)) {
      // If the user has set a non-PC/non-Interface as not embedded, correct it since not supported.
      // Note : this fails when using in the enhancer since not yet PC
      if (!api.isPersistable(elementTypeClass)
          && !elementTypeClass.isInterface()
          && elementTypeClass != java.lang.Object.class) {
        element.embedded = Boolean.TRUE;
      }
    }

    ElementMetaData elemmd = ((AbstractMemberMetaData) parent).getElementMetaData();
    if (elemmd != null && elemmd.getEmbeddedMetaData() != null) {
      element.embedded = Boolean.TRUE;
    }

    if (Boolean.TRUE.equals(element.dependent)) {
      // If the user has set a non-PC/non-reference as dependent, correct it since not valid.
      // Note : this fails when using in the enhancer since not yet PC
      if (!api.isPersistable(elementTypeClass)
          && !elementTypeClass.isInterface()
          && elementTypeClass != java.lang.Object.class) {
        element.dependent = Boolean.FALSE;
      }
    }

    // Keep a reference to the MetaData for the element
    element.classMetaData = mmgr.getMetaDataForClassInternal(elementTypeClass, clr);

    // Make sure anything in the superclass is populated too
    super.populate(clr, primary, mmgr);

    setPopulated();
  }
Ejemplo n.º 18
0
  /**
   * Method to populate any defaults, and check the validity of the MetaData.
   *
   * @param clr ClassLoaderResolver to use for loading any key/value types
   * @param primary the primary ClassLoader to use (or null)
   * @param mmgr MetaData manager
   */
  public void populate(ClassLoaderResolver clr, ClassLoader primary, MetaDataManager mmgr) {
    AbstractMemberMetaData mmd = (AbstractMemberMetaData) parent;
    if (!StringUtils.isWhitespace(key.type) && key.type.indexOf(',') > 0) {
      throw new InvalidMetaDataException(LOCALISER, "044143", mmd.getName(), mmd.getClassName());
    }
    if (!StringUtils.isWhitespace(value.type) && value.type.indexOf(',') > 0) {
      throw new InvalidMetaDataException(LOCALISER, "044144", mmd.getName(), mmd.getClassName());
    }

    ApiAdapter api = mmgr.getApiAdapter();

    // Make sure the type in "key", "value" is set
    key.populate(
        ((AbstractMemberMetaData) parent).getAbstractClassMetaData().getPackageName(),
        clr,
        primary,
        mmgr);
    value.populate(
        ((AbstractMemberMetaData) parent).getAbstractClassMetaData().getPackageName(),
        clr,
        primary,
        mmgr);

    // Check the field type and see if it is castable to a Map
    Class field_type = getMemberMetaData().getType();
    if (!java.util.Map.class.isAssignableFrom(field_type)) {
      throw new InvalidMetaDataException(
          LOCALISER, "044145", getFieldName(), getMemberMetaData().getClassName(false));
    }

    if (java.util.Properties.class.isAssignableFrom(field_type)) {
      // Properties defaults to <String, String>
      if (key.type == null) {
        key.type = String.class.getName();
      }
      if (value.type == null) {
        value.type = String.class.getName();
      }
    }

    // "key-type"
    if (key.type == null) {
      throw new InvalidMetaDataException(
          LOCALISER, "044146", getFieldName(), getMemberMetaData().getClassName(false));
    }

    // Check that the key type exists
    Class keyTypeClass = null;
    try {
      keyTypeClass = clr.classForName(key.type, primary);
    } catch (ClassNotResolvedException cnre) {
      try {
        // Maybe the user specified a java.lang class without fully-qualifying it
        // This is beyond the scope of the JDO spec which expects java.lang cases to be
        // fully-qualified
        keyTypeClass = clr.classForName(ClassUtils.getJavaLangClassForType(key.type), primary);
      } catch (ClassNotResolvedException cnre2) {
        throw new InvalidMetaDataException(
            LOCALISER, "044147", getFieldName(), getMemberMetaData().getClassName(false), key.type);
      }
    }

    if (!keyTypeClass.getName().equals(key.type)) {
      // The value-type has been resolved from what was specified in the MetaData - update to the
      // fully-qualified name
      NucleusLogger.METADATA.info(
          LOCALISER.msg(
              "044148",
              getFieldName(),
              getMemberMetaData().getClassName(false),
              key.type,
              keyTypeClass.getName()));
      key.type = keyTypeClass.getName();
    }

    // "embedded-key"
    if (key.embedded == null) {
      // Assign default for "embedded-key" based on 18.13.2 of JDO 2 spec
      if (mmgr.getNucleusContext().getTypeManager().isDefaultEmbeddedType(keyTypeClass)) {
        key.embedded = Boolean.TRUE;
      } else if (api.isPersistable(keyTypeClass)
          || Object.class.isAssignableFrom(keyTypeClass)
          || keyTypeClass.isInterface()) {
        key.embedded = Boolean.FALSE;
      } else {
        key.embedded = Boolean.TRUE;
      }
    }
    if (Boolean.FALSE.equals(key.embedded)) {
      // If the user has set a non-PC/non-Interface as not embedded, correct it since not supported.
      // Note : this fails when using in the enhancer since not yet PC
      if (!api.isPersistable(keyTypeClass)
          && !keyTypeClass.isInterface()
          && keyTypeClass != java.lang.Object.class) {
        key.embedded = Boolean.TRUE;
      }
    }
    KeyMetaData keymd = ((AbstractMemberMetaData) parent).getKeyMetaData();
    if (keymd != null && keymd.getEmbeddedMetaData() != null) {
      // If the user has specified <embedded>, set to true
      key.embedded = Boolean.TRUE;
    }

    // "value-type"
    if (value.type == null) {
      throw new InvalidMetaDataException(
          LOCALISER, "044149", getFieldName(), getMemberMetaData().getClassName(false));
    }

    // Check that the value-type exists
    Class valueTypeClass = null;
    try {
      valueTypeClass = clr.classForName(value.type);
    } catch (ClassNotResolvedException cnre) {
      try {
        // Maybe the user specified a java.lang class without fully-qualifying it
        // This is beyond the scope of the JDO spec which expects java.lang cases to be
        // fully-qualified
        valueTypeClass = clr.classForName(ClassUtils.getJavaLangClassForType(value.type));
      } catch (ClassNotResolvedException cnre2) {
        throw new InvalidMetaDataException(
            LOCALISER,
            "044150",
            getFieldName(),
            getMemberMetaData().getClassName(false),
            value.type);
      }
    }

    if (!valueTypeClass.getName().equals(value.type)) {
      // The value-type has been resolved from what was specified in the MetaData - update to the
      // fully-qualified name
      NucleusLogger.METADATA.info(
          LOCALISER.msg(
              "044151",
              getFieldName(),
              getMemberMetaData().getClassName(false),
              value.type,
              valueTypeClass.getName()));
      value.type = valueTypeClass.getName();
    }

    // "embedded-value"
    if (value.embedded == null) {
      // Assign default for "embedded-value" based on 18.13.2 of JDO 2 spec
      if (mmgr.getNucleusContext().getTypeManager().isDefaultEmbeddedType(valueTypeClass)) {
        value.embedded = Boolean.TRUE;
      } else if (api.isPersistable(valueTypeClass)
          || Object.class.isAssignableFrom(valueTypeClass)
          || valueTypeClass.isInterface()) {
        value.embedded = Boolean.FALSE;
      } else {
        value.embedded = Boolean.TRUE;
      }
    }
    if (value.embedded == Boolean.FALSE) {
      // If the user has set a non-PC/non-Interface as not embedded, correct it since not supported.
      // Note : this fails when using in the enhancer since not yet PC
      if (!api.isPersistable(valueTypeClass)
          && !valueTypeClass.isInterface()
          && valueTypeClass != java.lang.Object.class) {
        value.embedded = Boolean.TRUE;
      }
    }
    ValueMetaData valuemd = ((AbstractMemberMetaData) parent).getValueMetaData();
    if (valuemd != null && valuemd.getEmbeddedMetaData() != null) {
      // If the user has specified <embedded>, set to true
      value.embedded = Boolean.TRUE;
    }

    key.classMetaData = mmgr.getMetaDataForClassInternal(keyTypeClass, clr);
    value.classMetaData = mmgr.getMetaDataForClassInternal(valueTypeClass, clr);

    // Cater for Key with mapped-by needing to be PK (for JPA)
    if (keymd != null
        && keymd.mappedBy != null
        && keymd.mappedBy.equals("#PK")) // Special value set by JPAMetaDataHandler
    {
      // Need to set the mapped-by of <key> to be the PK of the <value>
      if (value.classMetaData.getNoOfPrimaryKeyMembers() != 1) {
        // TODO Localise this
        throw new NucleusUserException(
            "DataNucleus does not support use of <map-key> with no name field when the"
                + " value class has a composite primary key");
      }
      int[] valuePkFieldNums = value.classMetaData.getPKMemberPositions();
      keymd.mappedBy =
          value.classMetaData.getMetaDataForManagedMemberAtAbsolutePosition(valuePkFieldNums[0])
              .name;
    }

    // Make sure anything in the superclass is populated too
    super.populate(clr, primary, mmgr);

    setPopulated();
  }
Ejemplo n.º 19
0
  /**
   * Method to remove all elements from the collection from the TreeSet.
   *
   * @param elements The collection of elements to remove
   * @return Whether it was removed ok.
   */
  public boolean removeAll(java.util.Collection elements) {
    makeDirty();

    if (useCache) {
      loadFromStore();
    }

    int size = (useCache ? delegate.size() : -1);
    Collection contained = null;
    if (backingStore != null && SCOUtils.useQueuedUpdate(queued, ownerOP)) {
      // Check which are contained before updating the delegate
      contained = new java.util.HashSet();
      for (Object elem : elements) {
        if (contains(elem)) {
          contained.add(elem);
        }
      }
    }
    boolean delegateSuccess = delegate.removeAll(elements);

    if (ownerOP != null && ownerOP.getExecutionContext().getManageRelations()) {
      // Relationship management
      Iterator iter = elements.iterator();
      RelationshipManager relMgr = ownerOP.getExecutionContext().getRelationshipManager(ownerOP);
      while (iter.hasNext()) {
        relMgr.relationRemove(ownerMmd.getAbsoluteFieldNumber(), iter.next());
      }
    }

    if (backingStore != null) {
      boolean backingSuccess = true;
      if (SCOUtils.useQueuedUpdate(queued, ownerOP)) {
        backingSuccess = false;
        for (Object element : contained) {
          backingSuccess = true;
          ownerOP
              .getExecutionContext()
              .addOperationToQueue(
                  new CollectionRemoveOperation(ownerOP, backingStore, element, true));
        }
      } else {
        try {
          backingSuccess = backingStore.removeAll(ownerOP, elements, size);
        } catch (NucleusDataStoreException dse) {
          NucleusLogger.PERSISTENCE.warn(
              LOCALISER.msg("023013", "removeAll", ownerMmd.getName(), dse));
          backingSuccess = false;
        }
      }

      if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) {
        ownerOP.getExecutionContext().processNontransactionalUpdate();
      }

      return backingSuccess;
    } else {
      if (ownerOP != null && !ownerOP.getExecutionContext().getTransaction().isActive()) {
        ownerOP.getExecutionContext().processNontransactionalUpdate();
      }
      return delegateSuccess;
    }
  }
Ejemplo n.º 20
0
  /**
   * Method to initialise the table definition.
   *
   * @param clr The ClassLoaderResolver
   */
  public void initialize(ClassLoaderResolver clr) {
    assertIsUninitialized();

    MapMetaData mapmd = mmd.getMap();
    if (mapmd == null) {
      throw new NucleusUserException(LOCALISER.msg("057017", mmd));
    }

    PrimaryKeyMetaData pkmd =
        (mmd.getJoinMetaData() != null ? mmd.getJoinMetaData().getPrimaryKeyMetaData() : null);
    boolean pkColsSpecified = (pkmd != null && pkmd.getColumnMetaData() != null);
    boolean pkRequired = requiresPrimaryKey();

    // Add owner mapping
    ColumnMetaData[] ownerColmd = null;
    if (mmd.getJoinMetaData() != null
        && mmd.getJoinMetaData().getColumnMetaData() != null
        && mmd.getJoinMetaData().getColumnMetaData().length > 0) {
      // Column mappings defined at this side (1-N, M-N)
      // When specified at this side they use the <join> tag
      ownerColmd = mmd.getJoinMetaData().getColumnMetaData();
    }
    ownerMapping =
        ColumnCreator.createColumnsForJoinTables(
            clr.classForName(ownerType),
            mmd,
            ownerColmd,
            storeMgr,
            this,
            pkRequired,
            false,
            FieldRole.ROLE_OWNER,
            clr);
    if (NucleusLogger.DATASTORE.isDebugEnabled()) {
      debugMapping(ownerMapping);
    }

    String keyValueFieldName =
        (mmd.getKeyMetaData() != null ? mmd.getKeyMetaData().getMappedBy() : null);
    String valueKeyFieldName =
        (mmd.getValueMetaData() != null ? mmd.getValueMetaData().getMappedBy() : null);

    // Add key mapping
    boolean keyPC = (mmd.hasMap() && mmd.getMap().keyIsPersistent());
    Class keyCls = clr.classForName(mapmd.getKeyType());
    if (keyValueFieldName != null && isEmbeddedValuePC()) {
      // Added in value code
    } else if (isSerialisedKey()
        || isEmbeddedKeyPC()
        || (isEmbeddedKey() && !keyPC)
        || ClassUtils.isReferenceType(keyCls)) {
      // Key = PC(embedded), PC(serialised), Non-PC(serialised), Non-PC(embedded), Reference
      keyMapping = storeMgr.getMappingManager().getMapping(this, mmd, clr, FieldRole.ROLE_MAP_KEY);
      if (Boolean.TRUE.equals(mmd.getContainer().allowNulls())) {
        // Make all key col(s) nullable so we can store null elements
        for (int i = 0; i < keyMapping.getNumberOfDatastoreMappings(); i++) {
          Column elementCol = (Column) keyMapping.getDatastoreMapping(i).getDatastoreField();
          elementCol.setNullable();
        }
      }
      if (NucleusLogger.DATASTORE.isDebugEnabled()) {
        debugMapping(keyMapping);
      }
      if (valueKeyFieldName != null && isEmbeddedKeyPC()) {
        // Key (PC) is embedded and value is a field of the key
        EmbeddedKeyPCMapping embMapping = (EmbeddedKeyPCMapping) keyMapping;
        valueMapping = embMapping.getJavaTypeMapping(valueKeyFieldName);
      }
    } else {
      // Key = PC
      ColumnMetaData[] keyColmd = null;
      KeyMetaData keymd = mmd.getKeyMetaData();
      if (keymd != null
          && keymd.getColumnMetaData() != null
          && keymd.getColumnMetaData().length > 0) {
        // Column mappings defined at this side (1-N, M-N)
        keyColmd = keymd.getColumnMetaData();
      }
      keyMapping =
          ColumnCreator.createColumnsForJoinTables(
              keyCls, mmd, keyColmd, storeMgr, this, false, false, FieldRole.ROLE_MAP_KEY, clr);
      if (mmd.getContainer().allowNulls() == Boolean.TRUE) {
        // Make all key col(s) nullable so we can store null elements
        for (int i = 0; i < keyMapping.getNumberOfDatastoreMappings(); i++) {
          Column elementCol = (Column) keyMapping.getDatastoreMapping(i).getDatastoreField();
          elementCol.setNullable();
        }
      }
      if (NucleusLogger.DATASTORE.isDebugEnabled()) {
        debugMapping(keyMapping);
      }
    }

    // Add value mapping
    boolean valuePC = (mmd.hasMap() && mmd.getMap().valueIsPersistent());
    Class valueCls = clr.classForName(mapmd.getValueType());
    if (valueKeyFieldName != null && isEmbeddedKeyPC()) {
      // Added in key code
    } else if (isSerialisedValue()
        || isEmbeddedValuePC()
        || (isEmbeddedValue() && !valuePC)
        || ClassUtils.isReferenceType(valueCls)) {
      // Value = PC(embedded), PC(serialised), Non-PC(serialised), Non-PC(embedded), Reference
      valueMapping =
          storeMgr.getMappingManager().getMapping(this, mmd, clr, FieldRole.ROLE_MAP_VALUE);
      if (mmd.getContainer().allowNulls() == Boolean.TRUE) {
        // Make all value col(s) nullable so we can store null elements
        for (int i = 0; i < valueMapping.getNumberOfDatastoreMappings(); i++) {
          Column elementCol = (Column) valueMapping.getDatastoreMapping(i).getDatastoreField();
          elementCol.setNullable();
        }
      }
      if (NucleusLogger.DATASTORE.isDebugEnabled()) {
        debugMapping(valueMapping);
      }
      if (keyValueFieldName != null && isEmbeddedValuePC()) {
        // Value (PC) is embedded and key is a field of the value
        EmbeddedValuePCMapping embMapping = (EmbeddedValuePCMapping) valueMapping;
        keyMapping = embMapping.getJavaTypeMapping(keyValueFieldName);
      }
    } else {
      // Value = PC
      ColumnMetaData[] valueColmd = null;
      ValueMetaData valuemd = mmd.getValueMetaData();
      if (valuemd != null
          && valuemd.getColumnMetaData() != null
          && valuemd.getColumnMetaData().length > 0) {
        // Column mappings defined at this side (1-N, M-N)
        valueColmd = valuemd.getColumnMetaData();
      }
      valueMapping =
          ColumnCreator.createColumnsForJoinTables(
              clr.classForName(mapmd.getValueType()),
              mmd,
              valueColmd,
              storeMgr,
              this,
              false,
              true,
              FieldRole.ROLE_MAP_VALUE,
              clr);
      if (mmd.getContainer().allowNulls() == Boolean.TRUE) {
        // Make all value col(s) nullable so we can store null elements
        for (int i = 0; i < valueMapping.getNumberOfDatastoreMappings(); i++) {
          Column elementCol = (Column) valueMapping.getDatastoreMapping(i).getDatastoreField();
          elementCol.setNullable();
        }
      }
      if (NucleusLogger.DATASTORE.isDebugEnabled()) {
        debugMapping(valueMapping);
      }
    }

    // Add order mapping if required
    boolean orderRequired = false;
    if (mmd.getOrderMetaData() != null) {
      // User requested order column so add one
      orderRequired = true;
    } else if (requiresPrimaryKey() && !pkColsSpecified) {
      // PK is required so maybe need to add an index to form the PK
      if (isEmbeddedKeyPC()) {
        if (mmd.getMap().getKeyClassMetaData(clr, storeMgr.getMetaDataManager()).getIdentityType()
            != IdentityType.APPLICATION) {
          // Embedded key PC with datastore id so we need an index to form the PK
          orderRequired = true;
        }
      } else if (isSerialisedKey()) {
        // Serialised key, so need an index to form the PK
        orderRequired = true;
      } else if (keyMapping instanceof ReferenceMapping) {
        // ReferenceMapping, so have order if more than 1 implementation
        ReferenceMapping refMapping = (ReferenceMapping) keyMapping;
        if (refMapping.getJavaTypeMapping().length > 1) {
          orderRequired = true;
        }
      } else if (!(keyMapping instanceof PersistableMapping)) {
        // Non-PC, so depends if the key column can be used as part of a PK
        // TODO This assumes the keyMapping has a single column but what if it is Color with 4 cols?
        Column elementCol = (Column) keyMapping.getDatastoreMapping(0).getDatastoreField();
        if (!((RDBMSAdapter) storeMgr.getDatastoreAdapter())
            .isValidPrimaryKeyType(elementCol.getJdbcType())) {
          // Not possible to use this Non-PC type as part of the PK
          orderRequired = true;
        }
      }
    }
    if (orderRequired) {
      // Order/Adapter (index) column is required (integer based)
      ColumnMetaData orderColmd = null;
      if (mmd.getOrderMetaData() != null
          && mmd.getOrderMetaData().getColumnMetaData() != null
          && mmd.getOrderMetaData().getColumnMetaData().length > 0) {
        // Specified "order" column info
        orderColmd = mmd.getOrderMetaData().getColumnMetaData()[0];
        if (orderColmd.getName() == null) {
          orderColmd = new ColumnMetaData(orderColmd);
          if (mmd.hasExtension("adapter-column-name")) {
            // Specified "extension" column name
            // TODO Is this needed? The user can just specify <order column="...">
            orderColmd.setName(mmd.getValueForExtension("adapter-column-name"));
          } else {
            // No column name so use default
            DatastoreIdentifier id = storeMgr.getIdentifierFactory().newIndexFieldIdentifier(mmd);
            orderColmd.setName(id.getIdentifierName());
          }
        }
      } else {
        if (mmd.hasExtension("adapter-column-name")) {
          // Specified "extension" column name
          // TODO Is this needed? The user can just specify <order column="...">
          orderColmd = new ColumnMetaData();
          orderColmd.setName(mmd.getValueForExtension("adapter-column-name"));
        } else {
          // No column name so use default
          DatastoreIdentifier id = storeMgr.getIdentifierFactory().newIndexFieldIdentifier(mmd);
          orderColmd = new ColumnMetaData();
          orderColmd.setName(id.getIdentifierName());
        }
      }
      orderMapping =
          storeMgr
              .getMappingManager()
              .getMapping(int.class); // JDO2 spec [18.5] order column is assumed to be "int"
      ColumnCreator.createIndexColumn(
          orderMapping, storeMgr, clr, this, orderColmd, pkRequired && !pkColsSpecified);
      if (NucleusLogger.DATASTORE.isDebugEnabled()) {
        debugMapping(orderMapping);
      }
    }

    // Define primary key of the join table (if any)
    if (pkRequired) {
      if (pkColsSpecified) {
        // Apply the users PK specification
        applyUserPrimaryKeySpecification(pkmd);
      } else {
        // Define PK using JPOX rules
        if (orderRequired) {
          // Order column specified so owner+order are the PK
          orderMapping.getDatastoreMapping(0).getDatastoreField().setAsPrimaryKey();
        } else {
          // No order column specified so owner+key are the PK
          for (int i = 0; i < keyMapping.getNumberOfDatastoreMappings(); i++) {
            keyMapping.getDatastoreMapping(i).getDatastoreField().setAsPrimaryKey();
          }
        }
      }
    }

    state = TABLE_STATE_INITIALIZED;
  }
Ejemplo n.º 21
0
  /**
   * Method to initialise the SCO from an existing value.
   *
   * @param o The object to set from
   * @param forInsert Whether the object needs inserting in the datastore with this value
   * @param forUpdate Whether to update the datastore with this value
   */
  public void initialise(Object o, boolean forInsert, boolean forUpdate) {
    Collection c = (Collection) o;
    if (c != null) {
      // Check for the case of serialised PC elements, and assign ObjectProviders to the elements
      // without
      if (SCOUtils.collectionHasSerialisedElements(ownerMmd)
          && ownerMmd.getCollection().elementIsPersistent()) {
        ExecutionContext ec = ownerOP.getExecutionContext();
        Iterator iter = c.iterator();
        while (iter.hasNext()) {
          Object pc = iter.next();
          ObjectProvider objSM = ec.findObjectProvider(pc);
          if (objSM == null) {
            objSM =
                ec.newObjectProviderForEmbedded(
                    pc, false, ownerOP, ownerMmd.getAbsoluteFieldNumber());
          }
        }
      }

      if (backingStore != null && useCache && !isCacheLoaded) {
        // Mark as loaded
        isCacheLoaded = true;
      }

      if (forInsert) {
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
          NucleusLogger.PERSISTENCE.debug(
              LOCALISER.msg(
                  "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size()));
        }

        if (useCache) {
          loadFromStore();
        }
        if (ownerOP != null && ownerOP.getExecutionContext().getManageRelations()) {
          // Relationship management
          Iterator iter = c.iterator();
          RelationshipManager relMgr =
              ownerOP.getExecutionContext().getRelationshipManager(ownerOP);
          while (iter.hasNext()) {
            relMgr.relationAdd(ownerMmd.getAbsoluteFieldNumber(), iter.next());
          }
        }
        if (backingStore != null) {
          if (SCOUtils.useQueuedUpdate(queued, ownerOP)) {
            for (Object element : c) {
              ownerOP
                  .getExecutionContext()
                  .addOperationToQueue(new CollectionAddOperation(ownerOP, backingStore, element));
            }
          } else {
            try {
              backingStore.addAll(ownerOP, c, (useCache ? delegate.size() : -1));
            } catch (NucleusDataStoreException dse) {
              NucleusLogger.PERSISTENCE.warn(
                  LOCALISER.msg("023013", "addAll", ownerMmd.getName(), dse));
            }
          }
        }
        delegate.addAll(c);
        makeDirty();
      } else if (forUpdate) {
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
          NucleusLogger.PERSISTENCE.debug(
              LOCALISER.msg(
                  "023008", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size()));
        }

        // Detect which objects are added and which are deleted
        if (useCache) {
          isCacheLoaded = false; // Mark as false since need to load the old collection
          loadFromStore();

          for (Object elem : c) {
            if (!delegate.contains(elem)) {
              add(elem);
            }
          }
          java.util.TreeSet delegateCopy = new java.util.TreeSet(delegate);
          for (Object elem : delegateCopy) {
            if (!c.contains(elem)) {
              remove(elem);
            }
          }
        } else {
          for (Object elem : c) {
            if (!contains(elem)) {
              add(elem);
            }
          }
          Iterator iter = iterator();
          while (iter.hasNext()) {
            Object elem = iter.next();
            if (!c.contains(elem)) {
              remove(elem);
            }
          }
        }
      } else {
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
          NucleusLogger.PERSISTENCE.debug(
              LOCALISER.msg(
                  "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size()));
        }
        delegate.clear();
        delegate.addAll(c);
      }
    }
  }