0

JPA (hibernate provider) and Postgres 11

I have this configuration for my Id property (it's a single column/attribute PK).

For some reason after doing an INSERT into this table, JPA calls

select currval('yb.asset_store_id_seq')

I guess (I am not sure) it's doing it to refresh the Id of the newly inserted entity or maybe for some similar reason.

But there's no such sequence. My sequence is named yb.asset_store_seq and my table is yb.asset_store. My entity class is AssetStore.

So... how do I get rid of this issue? Basically JPA is somehow making up this sequence name out of nowhere. Or am I missing something ?!

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false, insertable=false, updatable=false)
private Integer id;

On the DB level, the sequence is owned by the table.

Here is the stack trace.

    Hibernate: 
        select
            currval('yb.asset_store_id_seq')
    Mar 25, 2020 3:45:02 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
    WARN: SQL Error: 0, SQLState: 42P01
    Mar 25, 2020 3:45:02 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
    ERROR: ERROR: relation "yb.asset_store_id_seq" does not exist
      Position: 16
    Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet


    ...................


        Caused by: org.postgresql.util.PSQLException: ERROR: relation "yb.asset_store_id_seq" does not exist
  Position: 16
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2183)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:308)
peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • Look at [this](https://stackoverflow.com/questions/60488292/). – SternK Mar 25 '20 at 19:58
  • @SternK Thanks... You mean I should use `hibernate.jdbc.use_get_generated_keys=true` or... ? This seems like a non-JPA standard i.e. some hibernate specific property... Is this the solution or... ? – peter.petrov Mar 25 '20 at 19:59
  • Yes, if your jdbc driver support it. It will allow to get rid of the `select currval('yb.asset_store_id_seq')` query. – SternK Mar 25 '20 at 20:03
  • That seems to work... But each question brings up 3-4 new ones :) Thanks. – peter.petrov Mar 25 '20 at 20:10
  • JPA doesn't define everything (it would make for a really bloated standard), so you need/can have implementation specific (Hibernate, EclipseLink, etc.) things as well. – Kayaman Mar 25 '20 at 20:19
  • Thanks guys. Your help is much appreciated. – peter.petrov Mar 25 '20 at 20:48

1 Answers1

1

First of all the hibernate documentation does not suggest to use GenerationType.IDENTITY strategy at all:

It is important to realize that using IDENTITY columns imposes a runtime behavior where the entity row must be physically inserted prior to the identifier value being known.

This can mess up extended persistence contexts (long conversations). Because of the runtime imposition/inconsistency, Hibernate suggests other forms of identifier value generation be used (e.g. SEQUENCE).

There is yet another important runtime impact of choosing IDENTITY generation: Hibernate will not be able to batch INSERT statements for the entities using the IDENTITY generation.

But if you can not change it, and you use the JDBC3+ driver and JRE1.4+. I would suggest to explicitly define:

<property name="hibernate.jdbc.use_get_generated_keys">true</property>

Because according to this

hibernate.jdbc.use_get_generated_keys (e.g. true or false)

Allows Hibernate to use JDBC3 PreparedStatement.getGeneratedKeys() to retrieve natively-generated keys after insert. You need the JDBC3+ driver and JRE1.4+. Disable this property if your driver has problems with the Hibernate identifier generators. By default, it tries to detect the driver capabilities from connection metadata.

It will allow to avoid your problem.

Community
  • 1
  • 1
SternK
  • 11,649
  • 22
  • 32
  • 46
  • Thanks. I don't understand a word from the first part. I am not sure whoever wrote it understands it too. "imposes a runtime behavior where the entity row must be physically inserted prior to the identifier value being known" >>> this sounds like a benefit to me, not a drawback... In fact I want my RDBMS to generate my keys, who else? "Hibernate will not be able to batch INSERT statements for the entities using the IDENTITY generation" >>> what does that mean, which scenarios are they referring to, any idea?! Regarding the 2nd part, thanks a lot, it really helped. – peter.petrov Mar 25 '20 at 20:44
  • "Because of the runtime imposition/inconsistency" What is this supposed to mean too? Under the hood my sequence is still called to generate the value for the Id column even when I use IDENTITY strategy. I checked that already. Anyway... I don't get this doc text even though I found it and read it too. Thanks again! – peter.petrov Mar 25 '20 at 20:50
  • As for `long conversations` look at [this](https://docs.jboss.org/hibernate/core/3.3/reference/en/html/transactions.html#transactions-basics-apptx). – SternK Mar 25 '20 at 20:58