78

I am performing hibernate jpa batch update and its giving me following error

2015-04-21 15:53:51,907 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (Thread-283 (HornetQ-client-global-threads-462057890)) SQL Error: 0, SQLState: 42P01
2015-04-21 15:53:51,908 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (Thread-283 (HornetQ-client-global-threads-462057890)) ERROR: relation "my_seq_gen" does not exist

I am using postgres database and my ID is auto generated

  @Id
@SequenceGenerator(name="seq-gen",sequenceName="MY_SEQ_GEN"initialValue=205, allocationSize=12)
@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="seq-gen")
@Column(name="\"ID\"",unique=true,nullable=false)
private int id;

This is my batch insert code snippet

getEm().getTransaction().begin();
System.out.println("transaction started--------------");
try {   
    for (Receipt ReceiptEntity : arrReceiptEntity) {
            getEm().persist(ReceiptEntity);
    }
    getEm().getTransaction().commit();
    System.out.println("commited");
} catch (Exception exception) {
    System.out.println("error----------------------------------------------------------------------");
    if(getEm().getTransaction().isActive())
        getEm().getTransaction().rollback();
    LOG.error(exception);
} finally {
    getEm().flush();
    getEm().clear();
    getEm().close();
}

I have added the following property in persistence.xml

         <property name="hibernate.id.new_generator_mappings" value="true"/>

Please suggest what i am doing wrong.

kirti
  • 4,499
  • 4
  • 31
  • 60

12 Answers12

118

Try to annotate your id with @Id and @GeneratedValue(strategy = GenerationType.IDENTITY).

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

UPDATE: It will only work if your id column was declared as SERIAL or BIGSERIAL types.

Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
Vsevolod Poletaev
  • 1,482
  • 1
  • 12
  • 13
  • 2
    Isn't IDENTITY is bad option for Postgresql? https://stackoverflow.com/questions/10041938/how-to-choose-the-id-generation-strategy-when-using-jpa-and-hibernate – Erlan Oct 27 '17 at 13:25
  • @Erlan I see no reason why it should be bad, neither from your link, nor from my experience. Can you explain your point? – Vsevolod Poletaev Oct 28 '17 at 09:20
  • 3
    @VsevolodPoletaev. Answers from link mentioned that IDENTITY is useful when there is no option of SEQUENCE because it will disable batch execution. But then found out that in hibernate 5 IDENTITY will bind id to SERIAL's sequence, so it should be ok. Thanks for answer. – Erlan Oct 31 '17 at 10:19
  • @Mikhail, you are right. It's written in docs http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-identity . But it's not important in most usecases. – Vsevolod Poletaev Mar 28 '18 at 09:47
  • Thanks for the tip and update! Spring Boot does the Rest! ;) – gleitonfranco Jan 18 '21 at 23:59
  • As far as I am concerned, your answer did the trick for me! I simply added basic identifier properties like not null and unique and all was good!! THUMBS UP – avi.elkharrat Feb 03 '22 at 22:19
33

If you don't want to change your entity definition, then you need to create a sequence in your postgreSQL schema with name hibernate_sequence.

CREATE SEQUENCE hibernate_sequence START 1;

UPDATE:

You are missing second sequence generatef, which you defined for your entity, just add it like previous one:

CREATE SEQUENCE my_seq_gen START 1;

What is a sequence?

Sequence is an ordered list of integers. The orders of numbers in the sequence are important. You can configure what is the min and max values, by what amount you should increment it:

CREATE SEQUENCE [ IF NOT EXISTS ] sequence_name
  [ AS { SMALLINT | INT | BIGINT } ]
  [ INCREMENT [ BY ] increment ]
  [ MINVALUE minvalue | NO MINVALUE ] 
  [ MAXVALUE maxvalue | NO MAXVALUE ]
  [ START [ WITH ] start ] 
  [ CACHE cache ] 
  [ [ NO ] CYCLE ]

No you can use functions like nextval('') in your SQL commands and in hibernate to get next value from the set. This is much cheaper than keepipng current primary key value in a sequence_table or looking for max PK value in existing table. So it provides an easy and cheap way to find next PK for given table.

All tables usually use a dedicated Sequance, and like in this example it was chosen as IdGenerator strategy.

Sore useful tutorial:

Beri
  • 11,470
  • 4
  • 35
  • 57
  • I have added sequence generator but its giving another error please check the updated question – kirti Apr 21 '15 at 13:57
  • As your exception says, you are still missing one sequence my_seq_gen, add it as previously. – Beri Apr 21 '15 at 19:14
  • Worked, like a charm, not sure what actually happens when you create the above sequence, if you could provide an explanation would be cherry on top. – xxx Oct 06 '21 at 15:15
10

I hope you get the answer but if you are still finding the answer this could be helpful.

I had same problem and resolved it annotating getter method of the id with @SequenceGenerator and @GeneratedValue.

@SequenceGenerator(name="seq-gen",sequenceName="MY_SEQ_GEN", initialValue=205, allocationSize=12)
@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="seq-gen")
public int getId(){
    return id;
}
biniam
  • 8,099
  • 9
  • 49
  • 58
Sameer
  • 109
  • 1
  • 3
  • No. It does not solve my problem. Still see `Hibernate: select nextval ('hibernate_sequence')` and this sequence does not exist initially in the schema. Have to create it manually like `CREATE SEQUENCE hibernate_sequence START 1;`, as the former answer. – WesternGun Feb 01 '19 at 13:55
4

Check application.properties file.

make sure that spring.jpa.hibernate.ddl-auto = update

Abdelsalam Megahed
  • 1,281
  • 12
  • 13
3

Can you try following :

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO, generator = "auto_gen")
  @SequenceGenerator(name = "auto_gen", sequenceName = "A")
  @Column(name = "ID")
  private int id;

Thanks

Mayur
  • 114
  • 6
  • I have added sequence generator but its giving another error please check the updated question – kirti Apr 21 '15 at 13:57
2

I was with the same problem.I solved puting auto increment on id column from the table on postgres it works, like that.

ALTER TABLE mytable ALTER COLUMN id SET DEFAULT nextval('mytable_id_seq');

ALTER SEQUENCE mytable_id_seq OWNED BY mytable.id; 
Nikolay Kostov
  • 16,433
  • 23
  • 85
  • 123
Sergeant
  • 21
  • 2
2

According to a post, hibernate could not get next sequence value , set your @GeneratedId column with strategy GenerationType.IDENTITY instead of GenerationType.SEQUENCE. So, you would have

@Id
@SequenceGenerator(name="seq-gen",sequenceName="MY_SEQ_GEN"initialValue=205, allocationSize=12)
@GeneratedValue(strategy= GenerationType.IDENTITY, generator="seq-gen")
@Column(name="\"ID\"",unique=true,nullable=false)
private int id;
Ifesinachi Bryan
  • 2,240
  • 1
  • 19
  • 20
2

Add the following to your application.properties

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update 

This will explicitly set to create or update all tables during Spring startup.

PrecisionLex
  • 801
  • 11
  • 26
1

In my case adding property name="hibernate.hbm2ddl.auto" value="update", solved the issue. You have to add the mentioned property in persistence.xml

  • 1
    Worked for me (but I tried with **create**). Watch out: This option deletes all the data from your database and is intended for development only. – El Mac May 02 '18 at 13:38
1

Sometimes with @Id @GeneratedValue(strategy=GenerationType.IDENTITY) annotation you can have your sequence with empty intervals (after delete) and incorrect next autoincrement position. Try to set next autoincrement value to the position after biggest id value:

ALTER SEQUENCE schema.entity_id_seq RESTART WITH 40072;
Zon
  • 18,610
  • 7
  • 91
  • 99
1
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
1

Recently I had the same issue and I have resolved it by using @GenericGenerator annotation. The issue was because I had to insert hundreds of rows with SQL statements in liquibase changelog and somehow hibernate does not pick up last row and its before generating id.

@Entity(name = "domain")
@Table(name = "domain", schema = "public")
public class DomainJpa {

    @Getter
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "incrementDomain")
    @GenericGenerator(name = "incrementDomain", strategy = "increment")
    private Integer id;

}

hopefully this can be useful for someone. Cheers :)

Doston
  • 579
  • 6
  • 15