Example usage for org.springframework.jdbc.support KeyHolder getKeys

List of usage examples for org.springframework.jdbc.support KeyHolder getKeys

Introduction

In this page you can find the example usage for org.springframework.jdbc.support KeyHolder getKeys.

Prototype

@Nullable
Map<String, Object> getKeys() throws InvalidDataAccessApiUsageException;

Source Link

Document

Retrieve the first map of keys.

Usage

From source file:ch.digitalfondue.npjt.QueryType.java

@SuppressWarnings("unchecked")
private static <T> AffectedRowCountAndKey<T> executeUpdateAndKeepKeys(String template, Method method,
        NamedParameterJdbcTemplate jdbc, SqlParameterSource parameters) {

    Class<T> keyClass = (Class<T>) ((ParameterizedType) method.getGenericReturnType())
            .getActualTypeArguments()[0];

    KeyHolder keyHolder = new GeneratedKeyHolder();

    int result = jdbc.update(template, parameters, keyHolder);
    Map<String, Object> keys = keyHolder.getKeys();
    Object key;/* www.j  a  v a2 s. com*/
    if (keys.size() > 1) {
        AutoGeneratedKey spec = Objects.requireNonNull(method.getDeclaredAnnotation(AutoGeneratedKey.class),
                "more than one key for query " + template + ": annotation @AutoGeneratedKey required");
        key = Objects.requireNonNull(keys.get(spec.value()), "the key with name " + spec.value()
                + " has returned null for query " + template + ": required a non null key");
    } else if (Number.class.isAssignableFrom(keyClass)) {
        Class<? extends Number> c = (Class<? extends Number>) keyClass;
        return new AffectedRowCountAndKey<>(result,
                (T) NumberUtils.convertNumberToTargetClass(keyHolder.getKey(), c));
    } else {
        key = keys.values().iterator().next();
    }
    return new AffectedRowCountAndKey<>(result, keyClass.cast(key));
}

From source file:com.bluecollarcoder.dao.RecipeRepository.java

public void persist(final Recipe recipe) {
    KeyHolder key = new GeneratedKeyHolder();
    jdbc.update((Connection con) -> {
        PreparedStatement stmt = con.prepareStatement(
                "insert into recipes (recipe_name, recipe_url, recipe_photo) values (?, ?, ?)",
                Statement.RETURN_GENERATED_KEYS);
        stmt.setString(1, recipe.getTitle());
        stmt.setString(2, recipe.getUrl());
        stmt.setString(3, recipe.getPhotoUrl());
        return stmt;
    }, key);/*  w ww.j a va  2 s .c  om*/

    Number recipeId = (Number) key.getKeys().get("recipe_id");

    for (String name : recipe.getIngredients().keySet()) {
        key = new GeneratedKeyHolder();
        jdbc.update((Connection con) -> {
            PreparedStatement stmt = con.prepareStatement(
                    "insert into ingredients (ingredient_name) values (?)", Statement.RETURN_GENERATED_KEYS);
            stmt.setString(1, name);
            return stmt;
        }, key);

        Number ingredientId = (Number) key.getKeys().get("ingredient_id");
        String amount = recipe.getIngredients().get(name);
        jdbc.update("insert into ingredient_amount (recipe_id, ingredient_id, amount) values (?, ?, ?)",
                new Object[] { recipeId, ingredientId, amount },
                new int[] { Types.INTEGER, Types.INTEGER, Types.VARCHAR });
    }
}

From source file:com.nortal.petit.core.dialect.PostgreSqlDialect.java

@SuppressWarnings("unchecked")
@Override//from   w w w .  j ava2  s. co m
public <B> B insertReturningId(JdbcOperations jdbcOperations, final String sql, String idColumn,
        final Object... params) {
    KeyHolder keyHolder = new GeneratedKeyHolder();
    jdbcOperations.update(new PreparedStatementCreator() {
        @Override
        public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
            PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            Object[] queryParams = params.length == 1 && params[0] instanceof Object[] ? (Object[]) params[0]
                    : params;
            ArgPreparedStatementSetter.setValues(ps, queryParams, 1);
            return ps;
        }
    }, keyHolder);
    return (B) keyHolder.getKeys().get(idColumn);
}

From source file:edu.jhuapl.openessence.datasource.jdbc.entry.JdbcOeDataEntrySource.java

/**
 * Executes INSERT SQL Statment using Spring's JdbcTemplate.
 *
 * @param tableName        table to insert values into
 * @param ignoreSpecialSql the flag to ignore specialSql definitions in the groovy def file. In general, set false
 *                         during add* and set true during update*
 * @param dimIds           DimensionIds that we will insert data for //todo ?? why is this needed?
 * @param editDims         editable DimensionIds that we will insert data for
 * @param values           values that correspond to the editable DimensionIds. These values get written into the
 *                         database//from   ww w  .j  av  a  2s  .  co m
 * @return Map of the primary keys and values for the inserted record -- only for the Parent Record - children return
 *         null
 * @throws OeDataSourceAccessException if error occurs at database level
 * @throws OeDataSourceException       if error occurs during processing
 */
private Map editableInsertQuery(String tableName, boolean ignoreSpecialSql, List<String> dimIds,
        Map<String, Dimension> editDims, Map<String, Object> values)
        throws OeDataSourceAccessException, OeDataSourceException {

    List<String> generatedKeys = new ArrayList<String>();
    Set<String> tablePkIds;

    // insert on parent table
    if (tableName.equals(parentTableDetails.getTableName())) {

        // setup KeyHolder from pk_dimIds
        tablePkIds = parentTableDetails.getPks();

        // setup autogen to sqlcol map
        Map<String, Object> superEditCopy = new LinkedHashMap<String, Object>(superEditMap);
        Set<String> superEditKeys = superEditCopy.keySet();
        DualHashBidiMap bidimap = new DualHashBidiMap();
        superEditKeys.retainAll(tablePkIds);
        for (Map.Entry<String, Object> e : superEditCopy.entrySet()) {
            e.setValue(((DimensionBean) e.getValue()).getSqlCol());
            bidimap.put(e.getKey(), e.getValue());
        }

        // setup KeyHolder from pk_dimIds
        generatedKeys.addAll(tablePkIds); // NOTE: jdbc driver clears this and puts in the autoincs it finds.
        Map<String, Object> generatedKeyMap = new HashMap<String, Object>();
        for (String eachKey : generatedKeys) {
            generatedKeyMap.put(eachKey, null);
        }
        List<Map<String, Object>> keyMapList = new ArrayList<Map<String, Object>>();
        keyMapList.add(generatedKeyMap);
        KeyHolder keyHolder = new GeneratedKeyHolder(keyMapList);

        jdbcTemplate.update(new MultiTableInsertPreparedStatementCreator(tableName, ignoreSpecialSql, dimIds,
                editDims, values), keyHolder);

        Map<String, Object> keyMap = keyHolder.getKeys();

        // TODO: current implementation of getGeneratedKeys for PGSQL 8.4 returns ALL column/vals...we just want the pk's we know about
        // TODO: CHECK FOR WHAT HAPPENS WITH LOWER/UPPER CASE
        //http://archives.postgresql.org/pgsql-jdbc/2010-04/msg00061.php
        boolean isPostgreSql = isPostgreSqlDBMS();
        if (isPostgreSql) {
            // postgres' implementation of keyholder lowercases the key column
            DbKeyValMap dbkvm = new DbKeyValMap(bidimap);
            Set<String> kyids = dbkvm.keySet();
            for (String ky : kyids) {
                dbkvm.put(ky, keyMap.get(bidimap.get(ky)));
            }
            kyids.retainAll(tablePkIds);
            keyMap = dbkvm;
        }

        // -OR-
        // if table had no auto-gen keys but the INSERT suceedes, means the pks taken from the 'values' worked.
        // therefore, safe to use these as the "generated" PKs. retains the values that are designated "PK" dimensions
        //
        else if (keyMap == null || keyMap.size() == 0) {
            DbKeyValMap dbkvm = new DbKeyValMap(values);
            Set<String> kyids = dbkvm.keySet();
            kyids.retainAll(tablePkIds);
            keyMap = dbkvm;
        }

        // make sure got *ALL* pkIds/values configured in the ds def.
        List<Map> allkeys = getAllGeneratedKeys(tableName, tablePkIds, new DbKeyValMap(keyMap));

        return (allkeys.size() > 0 ? allkeys.get(0) : null);

    } else { // insert on child table.
        // don't need to know the returned PK ids & vals for children. just do typical INSERT
        jdbcTemplate.update(new MultiTableInsertPreparedStatementCreator(tableName, ignoreSpecialSql, dimIds,
                editDims, values));
        return null;
    }
}

From source file:org.dcache.chimera.FsSqlDriver.java

/**
 *
 *  creates a new id for a tag and stores it into t_tags_inodes table.
 *
 * @param uid// www  .j  a  va  2 s .  c  o  m
 * @param gid
 * @param mode
 * @return
 */
long createTagInode(int uid, int gid, int mode) {
    final String CREATE_TAG_INODE_WITHOUT_VALUE = "INSERT INTO t_tags_inodes (imode, inlink, iuid, igid, isize, "
            + "ictime, iatime, imtime, ivalue) VALUES (?,1,?,?,0,?,?,?,NULL)";

    Timestamp now = new Timestamp(System.currentTimeMillis());
    KeyHolder keyHolder = new GeneratedKeyHolder();
    int rc = _jdbc.update(con -> {
        PreparedStatement ps = con.prepareStatement(CREATE_TAG_INODE_WITHOUT_VALUE,
                Statement.RETURN_GENERATED_KEYS);
        ps.setInt(1, mode | UnixPermission.S_IFREG);
        ps.setInt(2, uid);
        ps.setInt(3, gid);
        ps.setTimestamp(4, now);
        ps.setTimestamp(5, now);
        ps.setTimestamp(6, now);
        return ps;
    }, keyHolder);
    if (rc != 1) {
        throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(CREATE_TAG_INODE_WITHOUT_VALUE, 1, rc);
    }
    return (Long) keyHolder.getKeys().get("itagid");
}

From source file:org.dcache.chimera.FsSqlDriver.java

/**
 *
 *  creates a new id for a tag and stores it into t_tags_inodes table.
 *
 * @param uid// ww w. j  av a2s  . c  o m
 * @param gid
 * @param mode
 * @param value
 * @return
 */
long createTagInode(int uid, int gid, int mode, byte[] value) {
    final String CREATE_TAG_INODE_WITH_VALUE = "INSERT INTO t_tags_inodes (imode, inlink, iuid, igid, isize, "
            + "ictime, iatime, imtime, ivalue) VALUES (?,1,?,?,?,?,?,?,?)";

    Timestamp now = new Timestamp(System.currentTimeMillis());
    KeyHolder keyHolder = new GeneratedKeyHolder();
    int rc = _jdbc.update(con -> {
        PreparedStatement ps = con.prepareStatement(CREATE_TAG_INODE_WITH_VALUE,
                Statement.RETURN_GENERATED_KEYS);
        ps.setInt(1, mode | UnixPermission.S_IFREG);
        ps.setInt(2, uid);
        ps.setInt(3, gid);
        ps.setLong(4, value.length);
        ps.setTimestamp(5, now);
        ps.setTimestamp(6, now);
        ps.setTimestamp(7, now);
        ps.setBinaryStream(8, new ByteArrayInputStream(value), value.length);
        return ps;
    }, keyHolder);
    if (rc != 1) {
        throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(CREATE_TAG_INODE_WITH_VALUE, 1, rc);
    }
    return (Long) keyHolder.getKeys().get("itagid");
}

From source file:org.dcache.chimera.FsSqlDriver.java

/**
 *
 * creates an entry in t_inodes table with initial values.
 * for optimization, initial value of reference count may be defined.
 * for newly created files , file size is zero. For directories 512.
 *
 * @param id//from w w  w  . j a v a  2 s .c o m
 * @param uid
 * @param gid
 * @param mode
 * @param nlink
 */
Stat createInode(String id, int type, int uid, int gid, int mode, int nlink, long size) {
    Timestamp now = new Timestamp(System.currentTimeMillis());
    KeyHolder keyHolder = new GeneratedKeyHolder();
    _jdbc.update(con -> {
        PreparedStatement ps = con.prepareStatement(
                "INSERT INTO t_inodes (ipnfsid,itype,imode,inlink,iuid,igid,isize,iio,"
                        + "ictime,iatime,imtime,icrtime,igeneration) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)",
                Statement.RETURN_GENERATED_KEYS);
        ps.setString(1, id);
        ps.setInt(2, type);
        ps.setInt(3, mode & UnixPermission.S_PERMS);
        ps.setInt(4, nlink);
        ps.setInt(5, uid);
        ps.setInt(6, gid);
        ps.setLong(7, size);
        ps.setInt(8, _ioMode);
        ps.setTimestamp(9, now);
        ps.setTimestamp(10, now);
        ps.setTimestamp(11, now);
        ps.setTimestamp(12, now);
        ps.setLong(13, 0);
        return ps;
    }, keyHolder);

    Stat stat = new Stat();
    stat.setIno((Long) keyHolder.getKeys().get("inumber"));
    stat.setId(id);
    stat.setCrTime(now.getTime());
    stat.setGeneration(0);
    stat.setSize(size);
    stat.setATime(now.getTime());
    stat.setCTime(now.getTime());
    stat.setMTime(now.getTime());
    stat.setUid(uid);
    stat.setGid(gid);
    stat.setMode(mode & UnixPermission.S_PERMS | type);
    stat.setNlink(nlink);
    stat.setDev(17);
    stat.setRdev(13);

    return stat;
}

From source file:org.geoserver.jdbcconfig.internal.ConfigDatabase.java

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public <T extends Info> T add(final T info) {
    checkNotNull(info);/*from   w  ww . jav a 2 s . c  o  m*/
    checkNotNull(info.getId(), "Object has no id");
    checkArgument(!(info instanceof Proxy), "Added object shall not be a dynamic proxy");

    final String id = info.getId();

    byte[] value = binding.objectToEntry(info);

    final String blob = new String(value);
    final Class<T> interf = ClassMappings.fromImpl(info.getClass()).getInterface();
    final Integer typeId = dbMappings.getTypeId(interf);

    Map<String, ?> params = params("type_id", typeId, "id", id, "blob", blob);
    final String statement = String.format(
            "insert into object (oid, type_id, id, blob) values (%s, :type_id, :id, :blob)",
            dialect.nextVal("seq_OBJECT"));
    logStatement(statement, params);
    KeyHolder keyHolder = new GeneratedKeyHolder();
    int updateCount = template.update(statement, new MapSqlParameterSource(params), keyHolder,
            new String[] { "oid" });
    checkState(updateCount == 1, "Insert statement failed");
    // looks like some db's return the pk different than others, so lets try both ways
    Number key = (Number) keyHolder.getKeys().get("oid");
    if (key == null) {
        key = keyHolder.getKey();
    }
    addAttributes(info, key);

    cache.put(id, info);
    return getById(id, interf);
}

From source file:org.geoserver.jdbcconfig.internal.DbMappings.java

/**
 * @param infoClazz/*from  w ww. j  a v a 2s  .co  m*/
 * @param template
 * @param propertyName
 * @param targetProperty
 * @param isCollection
 * @return the newly added property type, or {@code null} if it was not added to the database
 *         (i.e. already exists)
 */
private PropertyType addPropertyType(final NamedParameterJdbcOperations template, final Class<?> infoClazz,
        final String propertyName, @Nullable final PropertyType targetProperty, final boolean isCollection,
        final boolean isText) {

    checkNotNull(template);
    checkNotNull(infoClazz);
    checkNotNull(propertyName);
    final Integer typeId = getTypeId(infoClazz);
    if (null == typeId) {
        throw new IllegalStateException("Unknown type id for " + infoClazz.getName());
    }

    Map<String, ?> params;

    log("Checking for ", propertyName);
    String query = "select count(*) from property_type "//
            + "where type_id = :objectType and name = :propName";
    params = params("objectType", typeId, "propName", propertyName);
    logStatement(query, params);
    final int exists = template.queryForInt(query, params);

    PropertyType pType;

    if (exists == 0) {
        log("Adding ", propertyName);

        Integer targetPropertyOid = targetProperty == null ? null : targetProperty.getOid();

        String insert = "insert into property_type (target_property, type_id, name, collection, text) "
                + "values (:target, :type, :name, :collection, :isText)";

        params = params("target", targetPropertyOid, "type", typeId, "name", propertyName, "collection",
                isCollection, "isText", isText);
        logStatement(insert, params);
        KeyHolder keyHolder = new GeneratedKeyHolder();
        template.update(insert, new MapSqlParameterSource(params), keyHolder);

        // looks like some db's return the pk different than others, so lets try both ways
        Number pTypeKey = (Number) keyHolder.getKeys().get("oid");
        if (pTypeKey == null) {
            pTypeKey = keyHolder.getKey();
        }

        pType = new PropertyType(pTypeKey.intValue(), targetPropertyOid, typeId, propertyName, isCollection,
                isText);
    } else {
        log("Not adding property type ", infoClazz.getSimpleName(), ".", propertyName, " as it already exists");
        pType = null;
    }

    if (pType != null) {
        Map<String, PropertyType> map = this.propertyTypes.get(typeId);
        if (map == null) {
            map = Maps.newHashMap();
            this.propertyTypes.put(typeId, map);
        }
        map.put(pType.getPropertyName(), pType);
    }
    return pType;
}