Search code examples
postgresqlhibernate

DEFAULT constraint not set by Hibernate


Here's a snippet from my entity:

@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "users")
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private UUID id;
    @Column(unique = true)
    private String username;
    private String password;
    @Column(columnDefinition = "SMALLINT CHECK (enabled IN(0,1)) DEFAULT 1")
    private Integer enabled;
    @OneToMany(mappedBy = "user")
    private Set<Role> authorities;

I have ddl-auto set to create-drop so Hibernate automatically created tables for me, here's one of the logs:

Hibernate: create table users (enabled SMALLINT CHECK (enabled IN(0,1)) DEFAULT 1, id uuid not null, password varchar(255), username varchar(255) unique, primary key (id))

However, what I found is that the DEFAULT constraint was not set for the table. It's Postgres

enter image description here

I also tried booleans and no chaining

Hibernate: create table users (enabled BOOLEAN DEFAULT true, id uuid not null, password varchar(255), username varchar(255) unique, primary key (id))

Still, no constraint

enter image description here

Does Postgres sees null as a regular value (a "third state", as described in the docs) so doesn't override the nulls it gets from JDBC?

What is my mistake?


Solution

  • Does Postgres sees null as a regular value (a "third state", as described in the docs) so doesn't override the nulls it gets from JDBC?

    Yes, the default will only be used if no value is provided. From the docs...

    When a new row is created and no values are specified for some of the columns, those columns will be filled with their respective default values. A data manipulation command can also request explicitly that a column be set to its default value, without having to know what that value is.

    null is not "no value", null is "the value is not known".

    If you want the default to be used, you must either not mention the column in your insert, or set it to DEFAULT.

    -- enabled is null
    insert into test(id, enabled) values (1, null);
    
    -- enabled use the default, false
    insert into test(id, enabled) (2, DEFAULT);
    insert into test(id) values (3);
    

    Demonstration.

    Most ORMs will insert their language's null value as a SQL null. If you want to use the SQL default, delete the key or set it to the literal (not a string) DEFAULT.

    And if the value cannot be null, be sure to add a not null constraint.