7

My entity has a mapOrder field which I want auto-increment like below:

@Entity
public class Map{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(columnDefinition = "serial")
    private Long mapOrder;

    //.......
}

The sql generated seems good:

CREATE TABLE map
(
  id bigserial NOT NULL,
  map_order serial NOT NULL,
  ...
)

But when I save it with Spring Data JPA's repository, like this:

Map m=new Map();
repo.save(m);

will give me exception:

Caused by: org.postgresql.util.PSQLException: ERROR: null value in column "map_order" violates not-null constraint

Any ideas?

July
  • 745
  • 3
  • 9
  • 21
  • Take a look: http://stackoverflow.com/questions/4979746/mapping-postgresql-serial-type-with-hibernate-annotations – user3707125 Jun 07 '15 at 04:49
  • you are using object Long, so default value is null. Also you have to specify the generation method for map_order – Safwan Hijazi Jun 07 '15 at 05:57
  • @user3707125 Thanks, the accepted answer works for me, though ```@Generated``` is not a JPA annotation. – July Jun 07 '15 at 06:21

2 Answers2

3

Try changing your code to this:

@GeneratedValue(strategy = GenerationType.SEQUENCE)

Reference: https://stackoverflow.com/a/29028369

Community
  • 1
  • 1
2

@GeneratedValue works with identifiers and you can't use it with regular fields.

You can, for example, use some object for sequences (with any key generation strategy):

@Entity
public class JpaNoPkSequence {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id", nullable=false, updatable=false)    
    private Long id;
}

For using the strategy GenerationType.SEQUENCE the sequence should be created in the database:

CREATE SEQUENCE JPA_PK_SEQ START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
ALTER SEQUENCE "JPA_PK_SEQ" OWNER TO something;

This should be specified in the key definition. You should also add a one-to-one relationship with the object that you will use to obtain sequences for regular fields:

@Entity 
public class Map {
    @Id
    @SequenceGenerator(name="jpaPkSeq", sequenceName="JPA_PK_SEQ", allocationSize=1, initialValue = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "jpaPkSeq")
    @Column(name = "id", nullable=false, updatable=false)
    private Long id;

    @OneToOne           
    private JpaNoPkSequence sequence;
    ...
}   

Hope this helps.