4

I have attribute in my Java entity like this:

@Basic(fetch = FetchType.LAZY) //I tried without this as well
@Column(name = "value_x", columnDefinition = "bigint default 0")
private Long valueX;

In table definition in pgAdmin I see:

value_x bigint DEFAULT 0,

but when object is inserted (with this attribute as null), column is empty/null not having 0 value inserted.

Anyone would know why it does not insert the default value? Using EclipseLink.

pirho
  • 11,565
  • 12
  • 43
  • 70
eXPRESS
  • 425
  • 2
  • 4
  • 19
  • A default value is not used by the JPA provider other than in table creation. If you want a 0 put in there then set that field in your class –  Jan 07 '19 at 09:41

2 Answers2

9

Null value is because JPA explicitly inserts a null value in to that column if no special handling is implemented. The columnDefinition does make the column creation with DEFAULT but it does not make JPA aware of/or obey it afterwards.

And it is a nullable column so there is no error. See what happens in plain SQL, think of this table:

create table example (
    col1 bigint default 42,
    col2 bigint default 99
);

Then make an insert like:

insert into example (col1) values (null);

then selecting:

select * from example;

would show result like:

col1 | col2
------+------
(null) | 99

If you need to have default values managed in the java side you need some special stuff in the Java side.

See for example this question and note that the accepted answer is not the working one but this answer. So setting the value when class is instantiated:

private Long valueX = 0;

Another way is as this answer for different question suggests, using @PrePersist:

@PrePersist
void prePersist() {
    if (this.valueX == null)
       this.valueX = 0;
}
pirho
  • 11,565
  • 12
  • 43
  • 70
  • Thanks, it works, if I understand correctly those two solutions renders the same output? (tested and it seems to behave the same) – eXPRESS Jan 07 '19 at 10:00
  • Yes. The only difference is that the `@PrePersist` is kind a _lazy_ initialization, it is done just before persisting by JPA. It might depend on the case which one is more suitable. – pirho Jan 07 '19 at 10:11
  • I went with plainly setting the value since it is cleaner but in case of having huge number of entries being created at once but persisted at different times (and the attribute being something maybe larger) I can see advantage in the prePersist. – eXPRESS Jan 07 '19 at 10:16
1

I found another way to resolve the same problem, because when I create my own object and persist in database and didn´t respect the DDL with default value.

So I looked at my console, and the SQL generated, and saw that insert came with all fields, but only one propertie in my object has the value changed.

So I put in the model class this annotation.

@DynamicInsert

When is inserting data, the framework not insert null values or values that are not modified, making the insert shorter.

Also has @DynamicUpdate annotation.

Diego Macario
  • 1,240
  • 2
  • 21
  • 33