⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractdomain.java

📁 把java对象映射成数据库表中的一条记录
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            "Null argument value for aJDBCHelper was passed to "
            +"AbstractDomain#validate(...)");
        }

    try
        {
        // Validate the supertype columnSpecs
        Iterator columnSpecs = i_columnSpecs.iterator(); // reset iterator
        while (columnSpecs.hasNext())
            {
            aColumnSpec = (ColumnSpec) columnSpecs.next();

            // If this attribute is required and not present, throw
            // MissingAttributeException.
            aColumnSpec.validateRequired(aPO);

            // If this attribute is unique, verify that no other rows match it.
            aColumnSpec.validateUnique(aPO,
                                       aJDBCHelper,
                                       i_primaryKeyColumnSpec,
                                       this.getDatabasePolicy(),
                                       i_tableName);
            } // while

        // Validate all subtype columnSpecs
        columnSpecs = i_subtypeColumnSpecs.iterator(); // reset iterator
        while (columnSpecs.hasNext())
            {
            aColumnSpec = (ColumnSpec) columnSpecs.next();

            // If this attribute is required and not present, throw
            // MissingAttributeException.
            aColumnSpec.validateRequired(aPO);

            // If this attribute is unique, verify that no other rows match it.
            aColumnSpec.validateUnique(aPO,
                                       aJDBCHelper,
                                       i_primaryKeyColumnSpec,
                                       this.getDatabasePolicy(),
                                       i_subtypeTableName);
            } // while
        }
    catch (MissingAttributeException e)
        {
        this.quietlyRollbackAndClose(aJDBCHelper);
        throw e;
        }
    catch (DuplicateRowException e)
        {
        this.quietlyRollbackAndClose(aJDBCHelper);
        throw e;
        }
    catch (DatabaseException e)
        {
        this.quietlyRollbackAndClose(aJDBCHelper);
        throw e;
        }

    } // validate(aPO, aJDBCHelper)


  /**
   * This is a pass-through method that adds the default JDBCHelper to the
   * argument list.  This method should not be overridden.
   *
   * @param aPO a value of type 'PersistentObject'
   * @return a value of type 'PersistentObject'
   * @exception ObjectHasChangedException if an error occurs
   * @exception MissingAttributeException if an error occurs
   * @exception DuplicateRowException if an error occurs
   */
  public final PersistentObject save(PersistentObject aPO)
          throws
          ObjectHasChangedException,
          MissingAttributeException,
          DuplicateRowException
    {
    return this.save(aPO, this.getJDBCHelper());
    } // save(aPersistentObject)


  /**
   * Save the PersistentObject to the database after validating the object
   * with this.validate(aPO,aJDBCHelper).
   *
   * Note for subclasses: If you don't want an exception from the validate
   * method to rollback your transaction, specifically call validate() with
   * a different JDBCHelper (a clone works) before calling save().
   *
   * @param aPO a value of type 'PersistentObject'
   *        if the primary key attribute is null, then this does a SQL insert.
   * @return a value of type 'PersistentObject'
   * @exception ObjectHasChangedException if an error occurs
   * @exception MissingAttributeException if an error occurs
   * @exception DuplicateRowException if an error occurs
   */
  public PersistentObject save(PersistentObject aPO,
                               JDBCHelper aJDBCHelper)
          throws
          ObjectHasChangedException,
          MissingAttributeException,
          DuplicateRowException
    {
    PersistentObject returnValue = null;

    if (LOG.isDebugEnabled())
        {
        LOG.debug("AbstractDomain.save(" + aPO + ", " + aJDBCHelper + ")");
        }
    if (aPO == null)
        {
        throw new IllegalArgumentException(
            "Null argument value for aPO was passed to "
            +"AbstractDomain#save(...)");
        }
    if (aJDBCHelper == null)
        {
        throw new IllegalArgumentException(
            "Null argument value for aJDBCHelper was passed to "
            +"AbstractDomain#save(...)");
        }

    // Throw an exception if trying to resave an old instance.
    if (aPO.hasDeadPersistentState())
        {
        throw new DatabaseException(
            "This instance has persistent state of \"dead\" and cannot be saved again. "
            + "If you wish to reuse instances, set ReturnSavedObject to false. "
            + "However, be warned that you won't get updated timestamps.");
        }

    // We don't want to begin (or end) a "transaction" if we are already in
    // one.  The given JDBCHelper might already be inside a transaction if
    // this method is being called from a preSave() or postSave() method of
    // another domain.
    boolean okToEndTransaction = false;
    if (!aJDBCHelper.isInsideTransaction())
        {
        // Tell JDBCHelper to ignore commit and close messages until
        // endTransaction() is called.
        this.beginTransaction(aJDBCHelper);
        okToEndTransaction = true;
        }


    // Clean-up and return the object if it doesn't require saving.
    // This is after the potential start of the transaction to ensure
    // proper clean-up of JDBCHelpers from a pool.
    // This could have been done before the beginTransaction with an explicit
    // check for pool usage, but this felt less error prone since this
    // will follow the same steps that would have occured if an update
    // did occur, and we know that works OK.
    if (aPO.hasCurrentPersistentState())
        {
        if (i_returnSavedObject)
            {
            returnValue = aPO;
            }
        if (okToEndTransaction)
            {
            // Tell JDBCHelper that it's OK to commit the transaction
            // and close (i.e. return to the pool if necessary) now.
            this.endTransaction(aJDBCHelper);
            }
        return returnValue;
        }

    // Perform any pre-validation logic defined by subclass.  This happens
    // before validating so it can be made valid if needed.
    this.preValidate(aPO, aJDBCHelper);

    if (i_validateBeforeSaving)
        {
        // Throw exception if object is not valid
        this.validate(aPO, aJDBCHelper);
        }

    // Perform any pre-save logic defined by subclass.  This happens after
    // validating so you can be sure the object is valid.
    this.preSave(aPO, aJDBCHelper);

    List columnSpecs = i_columnSpecs;

    if (aPO.hasNewPersistentState()) // this is an insert
        {
        this.doInsert(aPO,
                      aJDBCHelper,
                      i_tableName,
                      i_columnSpecs);

        // This block added for InstantDB, HypersonicSQL, and other
        // databases that use auto-increment
        if (this.getDatabasePolicy().autoIncrementIdentifier() != null &&
            i_primaryKeyColumnSpec.isSequencedPrimaryKey())
            {
            Long tempId = null;
            try
                {
                tempId = this.getDatabasePolicy().findAutoIncrementId(
                    this.getTableName(),
                    i_primaryKeyColumnSpec.getColumnName(),
                    aJDBCHelper);
                }
            catch (RuntimeException e)
                {
                this.quietlyRollbackAndClose(aJDBCHelper);
                throw e;
                }
            if (tempId == null)
                {
                this.quietlyRollbackAndClose(aJDBCHelper);
                throw new DatabaseException("Auto Increment Id is null");
                }

            i_primaryKeyColumnSpec.setValueTo(tempId, aPO);
            } // if we have a sequenced primary key

        // Insert into a subtype table if there is one.
        if (i_subtypeColumnSpecs.size() > 0)
            { // Insert into the Subtype table.
            List colSpecs = new ArrayList();
            colSpecs.add(i_primaryKeyColumnSpec);
            colSpecs.addAll(i_subtypeColumnSpecs);
            this.doInsert(aPO,
                          aJDBCHelper,
                          i_subtypeTableName,
                          colSpecs);
            } // if there is a subtype table
        } // if this is an insert
    else  // this is an update
        {
        UpdateSQLBuilder sqlBuilder = this.getUpdateSQLBuilder();
        String updateSQL = sqlBuilder.buildSQL(aPO,
                                               this.getTableName(),
                                               this.getColumnSpecs());
        int rowCount = this.executeSQLUpdate(updateSQL, aJDBCHelper);
        if (rowCount < 1)
            {
            this.quietlyRollbackAndClose(aJDBCHelper);
            throw new ObjectHasChangedException(
                this.find(aPO, aJDBCHelper));
            }

        // Insert to or update the subtype table if there is one.
        if (i_subtypeColumnSpecs.size() > 0)
            {
            // Check to see if we need to do an insert or an update
            // This adds an extra JDBC call, which I don't like, but there
            // is no db-neutral way (that I know of) to trap a
            // "row not found" error on an update.  Another solution might
            // be to have a subtype PersistentState in each PO.
            SelectSQLBuilder selectSQLBuilder = this.getSelectSQLBuilder();
            Integer i = this.findInteger(
                    selectSQLBuilder.buildCountSQL(i_subtypeTableName,
                                                   i_primaryKeyColumnSpec,
                                                   aPO,
                                                   this.getDatabasePolicy()));
            List colSpecs = new ArrayList();
            colSpecs.add(i_primaryKeyColumnSpec);
            colSpecs.addAll(i_subtypeColumnSpecs);
            if (i.intValue() == 0)
                { // Insert into the subtype table.
                this.doInsert(aPO,
                              aJDBCHelper,
                              i_subtypeTableName,
                              colSpecs);
                } // if we needed to insert
            else
                { // Update the subtype table.
                this.doUpdate(aPO,
                              aJDBCHelper,
                              i_subtypeTableName,
                              colSpecs);
                }
            }
        } // else

    // Perform any post-save logic defined by subclass.
    this.postSave(aPO, aJDBCHelper);

    // Return whatever got stored in the database.  This is needed because
    // timestamp and sequence columns can be changed during the JDBC call.
    if (i_returnSavedObject)
        {
        returnValue = this.finalFind(aPO, aJDBCHelper);
        aPO.forceDeadPersistentState();
        }
    else
        {
        // Assume the user knows the risks.
        aPO.forceCurrentPersistentState();
        }

    if (okToEndTransaction)
        {
        // Tell JDBCHelper that it's OK to commit the transaction now.
        this.endTransaction(aJDBCHelper);
        }

    return returnValue;
    } // save(aPO, aJDBCHelper)


  /** This method is here to help clean up the save() method a bit */
  private void doInsert(PersistentObject aPO,
                        JDBCHelper aJDBCHelper,
                        String tableName,
                        List columnSpecs)
    {
    String insertSQL =
        this.getInsertSQLBuilder().buildSQL(aPO,
                                            aJDBCHelper,
                                            tableName,
                                            columnSpecs);
    int rowCount = this.executeSQLUpdate(insertSQL, aJDBCHelper);
    if (rowCount < 1)
        {
        this.quietlyRollbackAndClose(aJDBCHelper);
        throw new DatabaseException(
            "Insert into table (" + tableName
            + ") failed.  Zero rows affected.");
        }
    } // doInsert(...)


  /** This method is here to help clean up the save() method a bit */
  private void doUpdate(PersistentObject aPO,
                        JDBCHelper aJDBCHelper,
                        String tableName,
                        List columnSpecs)
    {
    String sql =
        this.getUpdateSQLBuilder().buildSQL(aPO,
                                            tableName,
                                            columnSpecs);
    int rowCount = this.executeSQLUpdate(sql, aJDBCHelper);
    if (rowCount < 1)
        {
        this.quietlyRollbackAndClose(aJDBCHelper);
        throw new DatabaseException(
            "Update of table (" + tableName
            + ") failed.  Zero rows affected.");
        }
    } // doUpdate(...)


  /**
   * This is a pass-through method that adds the default JDBCHelper to the
   * argument list.
   *
   * @param aPO a value of type 'PersistentObject'
   * @return a value of type 'int'
   */
  public final int delete(PersistentObject aPO)
    {
    return this.delete(aPO, this.getJDBCHelper());
    }


  /**
   * Delete one row from the database.  No application exceptions need to be
   * declared here since the integer number of rows deleted is the return
   * value.
   *
   * @param aPO a value of type 'PersistentObject'
   * @return a value of type 'int' which is the number of rows deleted.
   *         This should always be zero or one, but this is not guaranteed
   *         if the wrong attribute is defined as the primary key.
   */
  public int delete(PersistentObject aPO,
                    JDBCHelper aJDBCHelper)
    {
    if (LOG.isDebugEnabled())
        {
        LOG.debug(
            "AbstractDomain.delete(" + aPO + ", " + aJDBCHelper + ")");
        }
    if (aPO == null)
        {
        throw new IllegalArgumentException(
            "A null value argument for aPO was passed to "
            + "AbstractDomain#delete(aPO,aJDBCHelper)");
        }
    if (aJDBCHelper == null)
        {
        throw new IllegalArgumentException(
            "A null value argument for aJDBCHelper was passed to "
            + "AbstractDomain#delete(aPO,aJDBCHelper)");
        }

    // We don't want to begin (or end) a "transaction" if we are already in
    // one.  We might already be inside a transaction if this method is
    // being called from a preSave(), preDelete(), postSave(), or
    // postDelete() method of another domain.
    boolean okToEndTransaction = false;
    if (!aJDBCHelper.isInsideTransaction())
        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -