示例#1
0
 /**
  * Enable/disable jdo Database pooling. This option only affects JDO if transactionManager is set
  * and a transaction is associated with the thread that call {@link #getDatabase}. If jdo Database
  * pooling is enabled, JDO will first search in the pool to see if there is already a Database for
  * the current transaction. If found, it returns the database; if not, it create a new one,
  * associates it will the transaction and return the newly created Database.
  *
  * <p>This method should be called before the invocation of {@link #getDatabase}.
  *
  * <p><b>Experimental</b> maybe removed in the future releases
  *
  * @param pool true to enable database pooling
  */
 public void setDatabasePooling(boolean pool) {
   if (!pool) {
     if (_txDbPool == null) return;
     else if (_txDbPool.isEmpty()) {
       _txDbPool = null;
       return;
     } else throw new IllegalStateException("JDO Pooling started. It can not be set to false");
   } else {
     if (_txDbPool == null) _txDbPool = new TxDatabaseMap();
     return;
   }
 }
示例#2
0
  /**
   * Opens and returns a connection to the database. Throws an {@link DatabaseNotFoundException} if
   * the database named was not set in the constructor or with a call to {@link #setDatabaseName},
   * or if no database configuration exists for the named database.
   *
   * @return An open connection to the database
   * @throws DatabaseNotFoundException Attempted to open a database that does not exist
   * @throws PersistenceException Database access failed
   */
  public Database getDatabase() throws DatabaseNotFoundException, PersistenceException {
    InputStream is;

    if (_dbName == null)
      throw new IllegalStateException("Called 'getDatabase' without first setting database name");
    if (DatabaseRegistry.getDatabaseRegistry(_dbName) == null) {
      if (_dbConf == null)
        throw new DatabaseNotFoundException(Messages.format("jdo.dbNoMapping", _dbName));
      try {
        DatabaseRegistry.loadDatabase(
            new InputSource(_dbConf), _entityResolver, _logInterceptor, _classLoader);
      } catch (MappingException except) {
        throw new DatabaseNotFoundException(except);
      }
    }

    if (_tmName != null) {
      InitialContext ctx;
      Transaction tx;
      DatabaseImpl dbImpl;

      try {
        if (tm == null) {
          ctx = new InitialContext();
          tm = (TransactionManager) ctx.lookup(_tmName);
        }
        tx = tm.getTransaction();
        if (_txDbPool != null && _txDbPool.containsTx(tx)) return _txDbPool.get(tx);

        if (tx != null && tx.getStatus() == Status.STATUS_ACTIVE) {
          dbImpl =
              new DatabaseImpl(
                  _dbName,
                  _lockTimeout,
                  _logInterceptor,
                  _callback,
                  _instanceFactory,
                  tx,
                  _classLoader,
                  _autoStore);

          if (_txDbPool != null) _txDbPool.put(tx, dbImpl);

          tx.registerSynchronization(dbImpl);
          return dbImpl;
        }
      } catch (NoInitialContextException except) {
        // No initial context. Just ignore.
      } catch (NameNotFoundException except) {
        // No TransactionManager object. Just ignore.
      } catch (Exception except) {
        // NamingException, SystemException, RollbackException
        if (_logInterceptor != null) _logInterceptor.exception(except);
      }
    }
    return new DatabaseImpl(
        _dbName,
        _lockTimeout,
        _logInterceptor,
        _callback,
        _instanceFactory,
        null,
        _classLoader,
        _autoStore);
  }
示例#3
0
  /**
   * Opens and returns a connection to the database. Throws an {@link DatabaseNotFoundException} if
   * the database named was not set in the constructor or with a call to {@link #setDatabaseName},
   * or if no database configuration exists for the named database.
   *
   * @return An open connection to the database
   * @throws DatabaseNotFoundException Attempted to open a database that does not exist
   * @throws PersistenceException Database access failed
   */
  public Database getDatabase() throws DatabaseNotFoundException, PersistenceException {
    if (_dbName == null)
      throw new IllegalStateException("Called 'getDatabase' without first setting database name");

    if (DatabaseRegistry.getDatabaseRegistry(_dbName) == null) {
      // use _jdoConfURI to load the JDO configuration
      if (_jdoConfURI != null)
        try {
          DatabaseRegistry.loadDatabase(
              new InputSource(_jdoConfURI), _entityResolver, _classLoader);
        } catch (MappingException except) {
          throw new DatabaseNotFoundException(except);
        }
      // alternatively, use a JdoConf instance to load the JDO configuration
      else if (_jdoConf != null) {
        try {
          DatabaseRegistry.loadDatabase(_jdoConf, _entityResolver, _classLoader);
        } catch (MappingException except) {
          throw new DatabaseNotFoundException(except);
        }
      } else throw new DatabaseNotFoundException(Messages.format("jdo.dbNoMapping", _dbName));
    }

    // load transaction manager factory registry configuration
    try {
      TransactionManagerFactoryRegistry.load(new InputSource(_jdoConfURI), _entityResolver);
    } catch (TransactionManagerAcquireException e) {
      throw new PersistenceException(
          Messages.message("jdo.transaction.problemToInitializeTransactionManagerFactory"), e);
    }

    if (_transactionManagerFactory == null) {

      String transactionMode = null;
      try {
        TransactionDemarcation demarcation =
            JDOConfLoader.getTransactionDemarcation(new InputSource(_jdoConfURI), _entityResolver);

        String demarcationMode = demarcation.getMode();

        org.exolab.castor.jdo.conf.TransactionManager transactionManager =
            demarcation.getTransactionManager();

        if (transactionManager != null) transactionMode = transactionManager.getName();
        else {

          if (demarcationMode.equals(LocalTransactionManagerFactory.NAME))
            transactionMode = LocalTransactionManagerFactory.NAME;
          else
            throw new PersistenceException(
                Messages.message("jdo.transaction.missingTransactionManagerConfiguration"));
        }

      } catch (MappingException e) {
        throw new PersistenceException("jdo.transaction.noValidTransactionMode", e);
      }

      /*
       * Try to obtain the specified<code>TransactionManagerFactory</code> instance from the
       * registry.
       *
       * If the returned TransactionManagerFactory instance is null,
       * return an exception to indicate that we cannot live without a
       * valid TransactionManagerFactory instance and that the user should
       * change her configuration.
       */
      _transactionManagerFactory =
          TransactionManagerFactoryRegistry.getTransactionManagerFactory(transactionMode);

      if (_transactionManagerFactory == null) {
        throw new DatabaseNotFoundException(
            Messages.format("jdo.transaction.missingTransactionManagerFactory", transactionMode));
      }

      /*
       *  Try to obtain a <code>javax.jta.TransactionManager>/code> from the factory.
       */
      try {
        _transactionManager = _transactionManagerFactory.getTransactionManager();
      } catch (TransactionManagerAcquireException e) {
        throw new DatabaseNotFoundException(
            Messages.format(
                "jdo.transaction.unableToAcquireTransactionManager",
                _transactionManagerFactory.getName(),
                e));
      }
    }

    /* At this point, we MUST have a valid instance of TransactionManagerFactory, and
     * dependent on its type (LOCAL or not), we MIGHT have a
     * valid<code>javax.jta.TransactionManager</code> instance.
     *
     * Scenario 1: If the user uses Castor in standalone mode (outside of an
     * J2EE container), we have a TransactionManagerFactory instance only,
     * but no TransactionManager instance.
     *
     * Scenario 2: If the user uses Castor in J2EE mode (inside of an J2EE
     * container), and wants the container to control transaction
     * demarcation, we have both a TransactionManagerFactory (different from
     * LOCAL) and a TransactionManager instance.
     */

    if ((!_transactionManagerFactory.getName().equals(LocalTransactionManagerFactory.NAME))
        && (_transactionManager != null)) {
      Transaction transaction;
      DatabaseImpl dbImpl;

      try {
        transaction = _transactionManager.getTransaction();
        if (_txDbPool != null && _txDbPool.containsTx(transaction))
          return _txDbPool.get(transaction);

        if (transaction != null && transaction.getStatus() == Status.STATUS_ACTIVE) {
          dbImpl =
              new DatabaseImpl(
                  _dbName,
                  _lockTimeout,
                  _callback,
                  _instanceFactory,
                  transaction,
                  _classLoader,
                  _autoStore);

          if (_txDbPool != null) _txDbPool.put(transaction, dbImpl);

          transaction.registerSynchronization(dbImpl);
          return dbImpl;
        }
      } catch (Exception except) {
        // NamingException, SystemException, RollbackException
        if (_logInterceptor != null) _logInterceptor.exception(except);
      }
    }

    return new DatabaseImpl(
        _dbName, _lockTimeout, _callback, _instanceFactory, null, _classLoader, _autoStore);
  }