alecswan
alecswan

Reputation: 499

Mapping PostgreSQL serial type with Hibernate annotations

I am using Hibernate 3.3 and PostgreSQL 8.x and would like to use Hibernate annotations to map an auto-incremented column which is NOT a primary key.

It doesn't matter if the column is mapped using SERIAL type or sequences in Postgres as long as it gets auto-incremented by the database and not by Hibernate. I tried the following mappings, but they always generated null orderId.

@Column(name = "orderId", insertable = false)
@Generated(GenerationTime.INSERT)
//@GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
private Integer orderId;

I will appreciate any help with this.

Thanks

Upvotes: 28

Views: 45920

Answers (5)

Klesun
Klesun

Reputation: 13723

I tried both GenerationTime.INSERT and GenerationType.IDENTITY, but neither prevented the null from being inserted on an updating saveAll() call.

What did help was marking the field as non-writable for hibernate:

@Column(insertable = false, updatable = false)
private Integer orderId;

(Kudos to this answer)

Upvotes: 1

erdikanik
erdikanik

Reputation: 744

Database sequence is not sync with your private key. So you need to update sequence index.

Check your sequence id from db and execute this sql command. (Do not forget to get backup your db just in case)

SELECT setval('your_primary_key_sequence', (SELECT MAX(your_primary_key) FROM your_table)+1);

Upvotes: 0

axtavt
axtavt

Reputation: 242716

The following mapping should work fine:

@Column(name = "orderId")
@Generated(GenerationTime.INSERT)
private Integer orderId;

Note, however, that generated value for freshly saved objects is not available until session is flushed.

EDIT: Note that this mapping doesn't affect doesn't make Hibernate to create a column of type serial during schema generation, since Hibernate doesn't know anything about the nature of value generation at the database side. Therefore, if you want Hibernate to create a column with a proper type, you need to specifiy it explicitly:

@Column(name = "orderId", columnDefinition = "serial")
@Generated(GenerationTime.INSERT)
private Integer orderId;

And on a recent Hibernate version (4.3), you can use this:

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

Upvotes: 37

pstanton
pstanton

Reputation: 36650

the accepted answer doesn't work for me.

this did though:

@Id
@Column(name = "your_id", columnDefinition = "serial")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer yourId;

Upvotes: 25

bjonczy
bjonczy

Reputation: 51

I'm using this with postgresql9.1, should work with 8 too:

@SequenceGenerator(allocationSize=1, initialValue=1, sequenceName="account_id_seq", name="account_id_seq")
@GeneratedValue(generator="account_id_seq", strategy=GenerationType.SEQUENCE)
@Id
@Column(name="id")
private Integer id;

Upvotes: 5

Related Questions