Ejemplo n.º 1
0
  /** Initialize the SEQUENCE key generator. */
  public SequenceKeyGenerator(PersistenceFactory factory, Properties params, int sqlType)
      throws MappingException {
    boolean returning;

    _factoryName = factory.getFactoryName();
    returning = "true".equals(params.getProperty("returning"));
    _triggerPresent = "true".equals(params.getProperty("trigger", "false"));

    if (!_factoryName.equals(OracleFactory.FACTORY_NAME)
        && !_factoryName.equals(PostgreSQLFactory.FACTORY_NAME)
        && !_factoryName.equals(InterbaseFactory.FACTORY_NAME)
        && !_factoryName.equals("sapdb")
        && !_factoryName.equals(DB2Factory.FACTORY_NAME)) {
      throw new MappingException(
          Messages.format("mapping.keyGenNotCompatible", getClass().getName(), _factoryName));
    }
    if (!_factoryName.equals(OracleFactory.FACTORY_NAME) && returning) {
      throw new MappingException(
          Messages.format(
              "mapping.keyGenParamNotCompat",
              "returning=\"true\"",
              getClass().getName(),
              _factoryName));
    }
    _factory = factory;
    _seqName = params.getProperty("sequence", "{0}_seq");

    _style =
        (_factoryName.equals(PostgreSQLFactory.FACTORY_NAME)
                || _factoryName.equals(InterbaseFactory.FACTORY_NAME)
                || _factoryName.equals(DB2Factory.FACTORY_NAME)
            ? BEFORE_INSERT
            : (returning ? DURING_INSERT : AFTER_INSERT));
    if (_triggerPresent && !returning) {
      _style = AFTER_INSERT;
    }
    if (_triggerPresent && _style == BEFORE_INSERT)
      throw new MappingException(
          Messages.format(
              "mapping.keyGenParamNotCompat",
              "trigger=\"true\"",
              getClass().getName(),
              _factoryName));

    _sqlType = sqlType;
    supportsSqlType(sqlType);

    try {
      _increment = Integer.parseInt(params.getProperty("increment", "1"));
    } catch (NumberFormatException nfe) {
      _increment = 1;
    }
  }
Ejemplo n.º 2
0
  /**
   * @param conn An open connection within the given transaction
   * @param tableName The table name
   * @param primKeyName The primary key name
   * @param props A temporary replacement for Principal object
   * @return A new key
   * @throws PersistenceException An error occured talking to persistent storage
   */
  public Object generateKey(Connection conn, String tableName, String primKeyName, Properties props)
      throws PersistenceException {
    PreparedStatement stmt = null;
    ResultSet rs;
    String seqName;
    String table;

    seqName =
        MessageFormat.format(
            _seqName,
            new String[] {tableName, primKeyName}); // due to varargs in 1.5, see CASTOR-1097
    table = _factory.quoteName(tableName);
    try {
      if (_factory.getFactoryName().equals(InterbaseFactory.FACTORY_NAME)) {
        // interbase only does before_insert, and does it its own way
        stmt =
            conn.prepareStatement(
                "SELECT gen_id(" + seqName + "," + _increment + ") FROM rdb$database");
        rs = stmt.executeQuery();
      } else if (_factory.getFactoryName().equals(DB2Factory.FACTORY_NAME)) {
        stmt = conn.prepareStatement("SELECT nextval FOR " + seqName + " FROM SYSIBM.SYSDUMMY1");
        rs = stmt.executeQuery();
      } else {
        if (_style == BEFORE_INSERT) {
          stmt = conn.prepareStatement("SELECT nextval('" + seqName + "')");
          rs = stmt.executeQuery();
        } else if (_triggerPresent && _factoryName.equals(PostgreSQLFactory.FACTORY_NAME)) {
          Object insStmt = props.get("insertStatement");
          Class psqlStmtClass = Class.forName("org.postgresql.Statement");
          Method getInsertedOID = psqlStmtClass.getMethod("getInsertedOID", (Class[]) null);
          int insertedOID = ((Integer) getInsertedOID.invoke(insStmt, (Object[]) null)).intValue();
          stmt =
              conn.prepareStatement(
                  "SELECT " + _factory.quoteName(primKeyName) + " FROM " + table + " WHERE OID=?");
          stmt.setInt(1, insertedOID);
          rs = stmt.executeQuery();

        } else {
          stmt =
              conn.prepareStatement(
                  "SELECT " + _factory.quoteName(seqName + ".currval") + " FROM " + table);
          rs = stmt.executeQuery();
        }
      }

      if (!rs.next()) {
        throw new PersistenceException(
            Messages.format("persist.keyGenFailed", getClass().getName()));
      }

      Object resultKey = null;
      int resultValue = rs.getInt(1);
      String resultColName = rs.getMetaData().getColumnName(1);
      int resultColType = rs.getMetaData().getColumnType(1);
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "JDBC query returned value "
                + resultValue
                + " from column "
                + resultColName
                + "/"
                + resultColType);
      }
      if (_sqlType == Types.INTEGER) {
        resultKey = new Integer(resultValue);
      } else if (_sqlType == Types.BIGINT) {
        resultKey = new Long(resultValue);
      } else if (_sqlType == Types.CHAR || _sqlType == Types.VARCHAR) {
        resultKey = String.valueOf(resultValue);
      } else {
        resultKey = new BigDecimal(resultValue);
      }

      if (LOG.isDebugEnabled()) {
        if (resultKey != null) {
          LOG.debug(
              "Returning value "
                  + resultKey
                  + " of type "
                  + resultKey.getClass().getName()
                  + " as key.");
        }
      }
      return resultKey;
    } catch (Exception ex) {
      throw new PersistenceException(
          Messages.format("persist.keyGenSQL", getClass().getName(), ex.toString()));
    } finally {
      JDOUtils.closeStatement(stmt);
    }
  }