0

I have class like Clazz

    @Table(
    name="tablename", 
    uniqueConstraints=
        @UniqueConstraint(
                          name= "uniqueColumn_deleted_uk",
                          columnNames={"myuniquecolumn", "deleted"}
                         )

    )
 public class Clazz {

     @Column(name = "deleted")
     private LocalDateTime deleted;
}

deleted is nullable, PosgreSQL creates unique index like

CREATE UNIQUE INDEX uniqueColumn_date_uk ON public.tablename (short_code_3, deleted);

and it allows insert duplicate myuniquecolumn when deleted is NULL.

How prevent this?

I want have non duplicates when deleted is null.

klin
  • 112,967
  • 15
  • 204
  • 232
Vazgen Torosyan
  • 1,255
  • 1
  • 12
  • 26

3 Answers3

2

You should create two partial unique indexes

create unique index on public.tablename (short_code_3, deleted) where deleted is not null;
create unique index on public.tablename (short_code_3) where deleted is null;

(I don't know how to do it in your ORM).

klin
  • 112,967
  • 15
  • 204
  • 232
0

This is not possible because null is never = null.

Read more about null values in SQL https://en.wikipedia.org/wiki/Null_(SQL)

If you want to have the deleted column in the unique index you must provide a default value for that column.

Simon Martinelli
  • 34,053
  • 5
  • 48
  • 82
0

Tow partial indexes like klin provided are best practice up to Postgres 14.

Postgres 15 adds NULLS NOT DISTINCT for this purpose:

CREATE UNIQUE INDEX foo_idx ON public.tbl (short_code_3, deleted) NULLS NOT DISTINCT;

See:

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228