コード例 #1
0
  /**
   * Execute statement to remove entity with given identity from database using given JDBC
   * connection.
   *
   * @param conn CastorConnection holding connection and PersistenceFactory to be used to create
   *     statement.
   * @param identity Identity of the object to remove.
   * @throws PersistenceException If failed to remove object from database. This could happen if a
   *     database access error occurs, type of one of the values to bind is ambiguous or object to
   *     be deleted does not exist.
   */
  public void executeStatement(final CastorConnection conn, final Identity identity)
      throws PersistenceException {
    CastorStatement stmt = conn.createStatement();
    try {
      stmt.prepareStatement(_delete);

      // bind the identity of the row to be stored into the preparedStatement
      for (ColumnValue value : _tableInfo.toSQL(identity)) {
        stmt.bindParameter(value.getName(), value.getValue(), value.getType());
      }

      if (LOG.isDebugEnabled()) {
        LOG.debug(Messages.format("jdo.removing", _type, stmt.toString()));
      }

      // execute prepared statement
      int result = stmt.executeUpdate();

      // throw exception if execute returned < 1
      if (result < 1) {
        throw new SQLException("Object to be deleted does not exist!");
      }
    } catch (SQLException ex) {
      LOG.fatal(Messages.format("jdo.deleteFatal", _type, stmt.toString()), ex);
      throw new PersistenceException(Messages.format("persist.nested", ex), ex);
    } finally {
      // close statement
      try {
        stmt.close();
      } catch (SQLException e) {
        LOG.warn("Problem closing JDBC statement", e);
      }
    }
  }
コード例 #2
0
  /**
   * Load key generator definitions, check for duplicate definitions and convert them to key
   * generator descriptors.
   *
   * @param mapping Mapping to load key generator defintions from.
   * @throws MappingException If mapping contains more then one key generator definition with same
   *     name.
   */
  private void createKeyGenDescriptors(final MappingRoot mapping) throws MappingException {
    Enumeration enumeration = mapping.enumerateKeyGeneratorDef();
    while (enumeration.hasMoreElements()) {
      KeyGeneratorDef def = (KeyGeneratorDef) enumeration.nextElement();

      // resolve name of the key generator definition; if there's an alias
      // defined, use it; if not, fall back to the name attribute (this
      // is to ensure that for one key generator type (e.g. HIGH-LOW), it is
      // possible to define more than one instance with individual
      // configuration(s).
      String name = def.getAlias();
      if (name == null) {
        name = def.getName();
      }

      KeyGeneratorDescriptor desc = _keyGeneratorDescriptors.get(name);
      if (desc != null) {
        throw new MappingException(Messages.format("mapping.dupKeyGen", name));
      }

      Properties params = new Properties();

      Enumeration enumerateParam = def.enumerateParam();
      while (enumerateParam.hasMoreElements()) {
        Param par = (Param) enumerateParam.nextElement();
        params.put(par.getName(), par.getValue());
      }

      desc = new KeyGeneratorDescriptor(name, def.getName(), params);

      _keyGeneratorDescriptors.put(name, desc);
    }
  }
コード例 #3
0
  /**
   * Initialize JDBC DataSource instance with the given database configuration instances and the
   * given class loader.
   *
   * @param database Database configuration.
   * @param loader ClassLoader to use.
   * @return The initalized DataSource.
   * @throws MappingException Problem related to analysing the JDO configuration.
   */
  public static DataSource loadDataSource(final Database database, final ClassLoader loader)
      throws MappingException {
    DataSource dataSource;
    Param[] parameters;

    DatabaseChoice dbChoice = database.getDatabaseChoice();
    String className = dbChoice.getDataSource().getClassName();
    ClassLoader classLoader = loader;
    if (classLoader == null) {
      classLoader = Thread.currentThread().getContextClassLoader();
    }

    try {
      Class dsClass = Class.forName(className, true, classLoader);
      dataSource = (DataSource) dsClass.newInstance();
    } catch (Exception e) {
      String msg = Messages.format("jdo.engine.classNotInstantiable", className);
      LOG.error(msg, e);
      throw new MappingException(msg, e);
    }

    parameters = database.getDatabaseChoice().getDataSource().getParam();
    setParameters(dataSource, parameters);

    return dataSource;
  }
コード例 #4
0
 /**
  * {@inheritDoc}
  *
  * @see org.castor.persist.AbstractTransactionContext
  *     #createConnection(org.exolab.castor.persist.LockEngine)
  */
 protected Connection createConnection(final LockEngine engine) throws ConnectionFailedException {
   // Get a new connection from the engine. Since the engine has no
   // transaction association, we must do this sort of round trip. An attempt
   // to have the transaction association in the engine inflates the code size
   // in other places.
   try {
     return engine.getDatabaseContext().getConnectionFactory().createConnection();
   } catch (SQLException ex) {
     throw new ConnectionFailedException(Messages.format("persist.nested", ex), ex);
   }
 }
コード例 #5
0
  public void unmarkReadOnly(final Object o) {
    _operation++;
    Object object = supportCGLibObject(o);

    if (!isTracking(object)) {
      throw new IllegalStateException(
          Messages.format(
              "persist.internal", "Attempt to make read-write object that is not in transaction"));
    }

    // Add it to our list of read only objects.
    _readWriteSet.add(object);
    _readOnlySet.remove(object);
  }
コード例 #6
0
  /**
   * Build SQL statement to remove entities of the type this class is responsible for.
   *
   * @param mapTo Table name retrieved from Class Descriptor trough JDO Nature.
   */
  private void buildStatement(final String mapTo) {
    // build condition for delete statement
    Condition condition = new AndCondition();
    for (ColumnInfo col : _tableInfo.getPrimaryKey().getColumns()) {
      String name = col.getName();
      condition.and(new Column(name).equal(new Parameter(name)));
    }

    // build delete class hierarchy that represents SQL query
    _delete = new Delete(mapTo);
    _delete.setCondition(condition);

    if (LOG.isTraceEnabled()) {
      LOG.trace(Messages.format("jdo.removing", _type, _delete.toString()));
    }
  }
コード例 #7
0
  /**
   * Set all the parameters of the given array at the given datasource by calling one of the set
   * methods of the datasource.
   *
   * @param dataSource The datasource to set the parameters on.
   * @param params The parameters to set on the datasource.
   * @throws MappingException If one of the parameters could not be set.
   */
  public static void setParameters(final DataSource dataSource, final Param[] params)
      throws MappingException {
    Method[] methods = dataSource.getClass().getMethods();

    for (int j = 0; j < params.length; j++) {
      String name = buildMethodName(params[j].getName());
      String value = params[j].getValue();

      boolean success = false;
      Exception cause = null;

      try {
        int i = 0;
        while (!success && (i < methods.length)) {
          Method method = methods[i];
          Class[] types = method.getParameterTypes();
          if ((method.getName().equals(name)) && (types.length == 1)) {
            if (types[0] == String.class) {
              method.invoke(dataSource, new Object[] {value});
              success = true;
            } else if (types[0] == int.class) {
              method.invoke(dataSource, new Object[] {new Integer(value)});
              success = true;
            } else if (types[0] == long.class) {
              method.invoke(dataSource, new Object[] {new Long(value)});
              success = true;
            } else if (types[0] == boolean.class) {
              method.invoke(dataSource, new Object[] {new Boolean(value)});
              success = true;
            }
          }
          i++;
        }
      } catch (Exception e) {
        cause = e;
      }

      if (!success || (cause != null)) {
        String msg = Messages.format("jdo.engine.datasourceParaFail", params[j].getName(), value);
        LOG.error(msg, cause);
        throw new MappingException(msg, cause);
      }
    }
  }
コード例 #8
0
  /**
   * {@inheritDoc}
   *
   * @see org.castor.persist.AbstractTransactionContext#closeConnections()
   */
  protected void closeConnections() throws TransactionAbortedException {
    // Go through all the connections opened in this transaction and close them
    // one by one. Close all that can be closed, after that report error if any.
    Exception error = null;

    Iterator iter = connectionsIterator();
    while (iter.hasNext()) {
      try {
        ((Connection) iter.next()).close();
      } catch (SQLException ex) {
        error = ex;
      }
    }
    clearConnections();

    if (error != null) {
      throw new TransactionAbortedException(Messages.format("persist.nested", error), error);
    }
  }
コード例 #9
0
  protected ClassDescriptor createClassDescriptor(final ClassMapping classMapping)
      throws MappingException {
    // If there is no SQL information for class, ignore it.
    if ((classMapping.getMapTo() == null) || (classMapping.getMapTo().getTable() == null)) {
      LOG.info(Messages.format("mapping.ignoringMapping", classMapping.getName()));
      return null;
    }

    // Create the class descriptor, and register the JDO nature with it.
    ClassDescriptorImpl clsDesc = new ClassDescriptorImpl();
    clsDesc.addNature(ClassDescriptorJDONature.class.getName());
    ClassDescriptorJDONature jdoNature = new ClassDescriptorJDONature(clsDesc);

    // Obtain the Java class.
    Class<?> javaClass = resolveType(classMapping.getName());
    if (!Types.isConstructable(javaClass, true)) {
      throw new MappingException("mapping.classNotConstructable", javaClass.getName());
    }
    clsDesc.setJavaClass(javaClass);

    // If this class extends another class, we need to obtain the extended
    // class and make sure this class indeed extends it.
    ClassDescriptor extDesc = getExtended(classMapping, javaClass);
    if (extDesc != null) {
      if (!(extDesc.hasNature(ClassDescriptorJDONature.class.getName()))) {
        throw new IllegalArgumentException("Extended class does not have a JDO descriptor");
      }

      new ClassDescriptorJDONature(extDesc).addExtended(clsDesc);
    }
    clsDesc.setExtends(extDesc);

    // If this class depends on another class, obtain the class it depends upon.
    clsDesc.setDepends(getDepended(classMapping, javaClass));

    // Create all field descriptors.
    FieldDescriptorImpl[] allFields = createFieldDescriptors(classMapping, javaClass);

    // Make sure there are no two fields with the same name.
    checkFieldNameDuplicates(allFields, javaClass);

    // Set class descriptor containing the field
    for (int i = 0; i < allFields.length; i++) {
      allFields[i].setContainingClassDescriptor(clsDesc);
    }

    // Identify identity and normal fields. Note that order must be preserved.
    List<FieldDescriptor> fieldList = new ArrayList<FieldDescriptor>(allFields.length);
    List<FieldDescriptor> idList = new ArrayList<FieldDescriptor>();
    if (extDesc == null) {
      // Sort fields into 2 lists based on identity definition of field.
      for (int i = 0; i < allFields.length; i++) {
        if (!allFields[i].isIdentity()) {
          fieldList.add(allFields[i]);
        } else {
          idList.add(allFields[i]);
        }
      }

      if (idList.size() == 0) {
        // Found no identities based on identity definition of field.
        // Try to find identities based on identity definition on class.
        String[] idNames = classMapping.getIdentity();
        if ((idNames == null) || (idNames.length == 0)) {
          // There are also no identity definitions on class.
          throw new MappingException("mapping.noIdentity", javaClass.getName());
        }

        FieldDescriptor identity;
        for (int i = 0; i < idNames.length; i++) {
          identity = findIdentityByName(fieldList, idNames[i], javaClass);
          if (identity != null) {
            idList.add(identity);
          } else {
            throw new MappingException("mapping.identityMissing", idNames[i], javaClass.getName());
          }
        }
      }
    } else {
      // Add all fields of extending class to field list.
      for (int i = 0; i < allFields.length; i++) {
        fieldList.add(allFields[i]);
      }

      // Add all identities of extended class to identity list.
      FieldDescriptor[] extIds = ((ClassDescriptorImpl) extDesc).getIdentities();
      for (int i = 0; i < extIds.length; i++) {
        idList.add(extIds[i]);
      }

      // Search redefined identities in extending class.
      FieldDescriptor identity;
      for (int i = 0; i < idList.size(); i++) {
        String idName = (idList.get(i)).getFieldName();
        identity = findIdentityByName(fieldList, idName, javaClass);
        if (identity != null) {
          idList.set(i, identity);
        }
      }
    }

    // Set identities on class descriptor.
    FieldDescriptor[] ids = new FieldDescriptor[idList.size()];
    clsDesc.setIdentities(idList.toArray(ids));

    // Set fields on class descriptor.
    FieldDescriptor[] fields = new FieldDescriptor[fieldList.size()];
    clsDesc.setFields(fieldList.toArray(fields));

    jdoNature.setTableName(classMapping.getMapTo().getTable());

    // Set the field name used for object modification checks.
    jdoNature.setVersionField(classMapping.getVersion());

    extractAndSetAccessMode(jdoNature, classMapping);
    extractAndAddCacheParams(jdoNature, classMapping, javaClass);
    extractAndAddNamedQueries(jdoNature, classMapping);
    extractAndAddNamedNativeQueries(jdoNature, classMapping);
    extractAndSetKeyGeneratorDescriptor(jdoNature, classMapping.getKeyGenerator());

    return clsDesc;
  }