1

spring-boot-starter-parent 2.4.1

spring-boot-starter-data-jpa

postgres 12.5

A short excerpt from an entity:

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter    

@Entity
public class Branch extends BaseEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;    

    @Column(columnDefinition = "varchar(255) default ''", nullable = false)
    private String name;

    @Column(columnDefinition = "varchar(255) default ''")
    private String segmentFour;
}

The entity generates a table like this:

This is it:

ads=# \d clients__branch

                                          Table "public.clients__branch"
            Column         |          Type          | Collation | Nullable |             Default              
    -----------------------+------------------------+-----------+----------+----------------------------------
     id                    | integer                |           | not null | generated by default as identity
     name                  | character varying(255) |           | not null | ''::character varying
     segment_four          | character varying(255) |           |          | ''::character varying
 

We can see that:

  1. "name" is not null and has a default value ''.
  2. "segment_one" has a default value, but there is no not null constraint.

Let's try to use this.

Let's fill the data and save it:

Branch branch0 = new Branch();
branch0.setName("Train");
branch0.setSegmentFour("");


Branch branch1 = new Branch();
branch1.setName("Car");
branch1.setSegmentFour(null);

Branch branch2 = new Branch();
branch2.setName("Ship");

Result:

ads=# select id, name, case when segment_four is null then 'null' when segment_four = '' then 'space' end as segment from clients__branch;
 id |  name   | segment 
----+---------+---------
  1 | Vosst   | space
  2 | Ryba    | null
  3 | Admiral | null

Problems

  1. I'd like to prevent anybody to from setting Null as in case with branch1.

  2. If I organize it like this:

    @Column(columnDefinition = "varchar(255) default ''", nullable = false) private String segmentFour;

    then I get:

    ERROR: null value in column "segment_four" violates not-null constraint
    
  3. I'd like to have a default value (the code for branch2 should generate '' in the segment_four).

Could you help me?

0

2 Answers 2

2

I would suggest you to use @ColumnDefault with @DynamicInsert in the following way:

@Entity
@DynamicInsert
public class Branch extends BaseEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;    

    @Column
    @ColumnDefault("''")
    private String name;

    @Column
    @ColumnDefault("''")
    private String segmentFour;
    
    // ...
}

and then just omit to set value for the field if you want to use the default value. The entity above is annotated with the @DynamicInsert annotation so that the INSERT statement does not include any entity attribute that does not contain a value.

See additional explanation in the documentation.

Sign up to request clarification or add additional context in comments.

Comments

0

I don't think there is a direct way to handle this using @Column annotation, but you can own logic in the setter method to make it to empty if value is null

public void setSegmentFour(String segmentFour) {
 this.segmentFour = segmentFour == null ? "" : segmentFour;
 }

5 Comments

It is too complicated. It will bring tons of code here. Now I use lombok's getter, setter.
I guess it is only one extra line, even lombok creats the same code without that condition @Kifsif
it is just an example. I'll have to refactor tons of code in a real project. For every field.
maybe lombok setter can have a default value?
A simpler approach is to initialize the field at its declaration (private String segmentFour = "";). Then you don't have to give the accessor methods side-effects. Of course this won't cover the scenario when someone explicitly sets a field to null, which is covered by the above solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.