Search code examples
javaspringpostgresqlhibernate

PostgreSQL default value don't work in Spring/Hibernate application


There is an application on Spring/Hibernate. I am using the PostgreSQL-database. I created the table with this script:

create table competence_aud
(
    ctl_validfrom     timestamp(6) not null default current_timestamp,
    pk                int8,
    employee          int8,
    competence        int8,
    lastupdatedwhen   timestamp(6)
);

I assume, that, if the date is NULL, then the current date will be inserted into the table (because I use current_timestamp).

Then, in the code I created this class:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "competence_aud")
@SourceEntity(schema = Schemas.core, table = "competence")
public class CompetenceAudEntity implements Record<Long> {

    @Id
    @Column(name = "pk")
    private long pk;

    @Column(name = "ctl_validfrom")
    private Timestamp ctlValidfrom;

    @Column(name = "employee")
    private Long employee;

    @Column(name = "competence")
    private Long competence;

    @Column(name = "lastupdatedwhen")
    private Timestamp lastupdatedwhen;

    @Override
    public Long getObjectId() {
        return pk;
    }

    public void setLastupdatedwhen(Timestamp lastupdatedwhen) {
        this.lastupdatedwhen = lastupdatedwhen;
        this.ctlValidfrom = lastupdatedwhen;
    }

}

I start the application. And in the case, when I get NULL value for a date, I see the error in the logs:

o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: null value in column "ctl_validfrom" of relation "competence_aud" violates not-null constraint
  Detail: Failing row contains (null, 22, 474, 546, null).

I think, the current_timestamp does not work at all :-(
Can you explain, why this is happening? How I must change my code?


Solution

  • When the CompetenceAudEntity object is inserted into the table, Spring will generate something like the following sql code:

    insert into competence_aud (ctl_validfrom, pk, employee, competence, lastupdatedwhen) values (null, 22, 474, 546, null)
    

    Since Spring explicitly passes null in the ctl_validfrom field, current_timestamp does not fire and does not generate a value automatically.

    To solve your problem, I suggest generating the current time before writing to the database. To do this, use the annotation org.hibernate.annotations.CreationTimestamp

    example:

    @Entity
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Table(name = "competence_aud")
    @SourceEntity(schema = Schemas.core, table = "competence")
    public class CompetenceAudEntity implements Record<Long> {
    
        @Id
        @Column(name = "pk")
        private long pk;
    
        @Column(name = "ctl_validfrom")
        @CreationTimestamp
        private Timestamp ctlValidfrom;
    
        @Column(name = "employee")
        private Long employee;
    
        @Column(name = "competence")
        private Long competence;
    
        @Column(name = "lastupdatedwhen")
        private Timestamp lastupdatedwhen;
    
       ...
    
    }