Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring jdbc and composite primary keys

Tags:

java

spring

jdbc

Is there a way in spring jdbc to return a composite primary key when a row is inserted. This composite primary key is made up of values from separate sequences

Any help is greatly appreciated

Regards Damien

like image 206
Damien Avatar asked Jun 28 '10 15:06

Damien


People also ask

What is composite primary key in JPA?

A composite primary key, also called a composite key, is a combination of two or more columns to form a primary key for a table. In JPA, we have two options to define the composite keys: the @IdClass and @EmbeddedId annotations.

How do you represent composite key in spring boot?

In order to create a composite key relationship in spring boot, we will create two classes where the identity class would be annotated with the @Embeddable annotation and the other class would contain a parameter annotated with the @EmbeddedId annotation.

Can primary key be composite?

A table can have only one primary key, which may consist of single or multiple fields. When multiple fields are used as a primary key, they are called a composite key. If a table has a primary key defined on any field(s), then you cannot have two records having the same value of that field(s).

What is the difference between Spring JDBC and Spring Data JDBC?

If you use Spring JDBC you will write queries that are executed directly on the database by JdbcTemplate. If you insert data with Spring Data JPA or Spring Data JDBC, you can use the entity or aggregate system that was created.


1 Answers

Here is a full example (tested on PostgreSQL 8.4):

My table:

CREATE TABLE test
(
  id serial NOT NULL,
  otherid serial NOT NULL,
  val text,
  CONSTRAINT test_pkey PRIMARY KEY (id, otherid)
)

This is how you get keys back:

public void doStuff() {
    KeyHolder keyHolder = new GeneratedKeyHolder();
    jdbcTemplate.update(
            new PreparedStatementCreator() {
                public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                    PreparedStatement ps = connection.prepareStatement("insert into test(val) values (?)", Statement.RETURN_GENERATED_KEYS);
                    ps.setInt(1, 42);
                    return ps;
                }
            },
            keyHolder);

    keyHolder.getKeys().get("id");
    keyHolder.getKeys().get("otherid");
}

Now, if you want to get your composite key as an instance of some class directly from keyHolder, it is not simple.

JdbcTemplate uses ColumnMapRowMapper to map generated keys (generated keys are returned as result set, at least on PostgreSQL. It actually returns the whole row as if you were executing select on the row you just inserted). Same ColumnMapRowMapper is used in number of other places in JdbcTemplate.

The only possible point of extension here is KeyHolder itself. Here is what you can do:

public void doStuff() {
    CompositeKeyHolder keyHolder = new CompositeKeyHolder();
    ... same code here ...

    keyHolder.getCompositeKey();
}


class CompositeKeyHolder extends GeneratedKeyHolder {
    private boolean converted;

    public CompositeKey getCompositeKey() {
        return new CompositeKey((Integer)this.getKeys().get("id"), (Integer)this.getKeys().get("otherid"));
    }
}


class CompositeKey {

    private Integer id;

    private Integer otherId;

    CompositeKey(Integer id, Integer otherId) {
        this.id = id;
        this.otherId = otherId;
    }

    public Integer getId() {
        return id;
    }

    public Integer getOtherId() {
        return otherId;
    }

}
like image 138
Georgy Bolyuba Avatar answered Sep 28 '22 12:09

Georgy Bolyuba