12

I have a very confusing problem stealing a lot of time:

@Column(name = "created", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP", insertable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date created;

This code the timestamp is set in my Postgres DB but the repository returns a entity with created = null;

I've tried some annotations like:

@Generated

from : Spring Data JPA JpaRepository.save(entity) not returning database default values

But nothing worked for me.

2
  • Did you try the @GeneratedValue annotation? Commented May 19, 2015 at 14:02
  • It's probably because of the updatable=false and passing null. Related: stackoverflow.com/questions/42023070/… Commented Nov 19, 2023 at 18:46

2 Answers 2

13

The generated values are only guaranteed to be generated at flush time. Saving an entity only makes it "attached" to the persistence context. So, either you have to flush the entity manager explicitely.

Try to use entity.saveAndFlush() and it should work.

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

3 Comments

In my case, I have a column modified_at and default value is current datetime. The only thing that worked for me was @UpdateTimestamp. I did not need to call .flush(). Neither @Generated or @GeneratedValue annotations worked, even after using .flush() the field would still come back as null after a .save().
thx I was suspicious about the Transaction not completly over as I was trying to generate modification and creation date on my entity. But the value is probably inserted after the entity save.
When I save my object with an already existing ID, it does return me only the @UpdateTimestamp bound field, not the @CreationTimestamp field ... (null value)
10

Using Spring Data we were facing the same issue with sql server

We solved it using

import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;

@Generated(GenerationTime.INSERT)
@Column(name = "created", insertable = false, updatable = false)
private LocalDateTime created;

You can combine it saveAndFlush (From JpaRepository)

If nothing works you can either implement refresh method by extending SimpleJpaRepository or avoid using the database default and replace it with an EntityListener

@EnableJpaAuditing
public class ConfigClass {...}


@EntityListeners(AuditingEntityListener.class)
public class YourEntity {

    @Column(name = "created", insertable = false, updatable = false)
    @CreatedDate
    private LocalDateTime created;
}

Take in consideration that using EntityListener you have to remove the database default. You could set insertable=true and use ColumnTransformer

    @Column(name = "created", updatable = false)
    @ColumnTransformer(write = "coalesce(sysutcdatetime(), ?)")
    @CreatedDate
    private LocalDateTime created;

1 Comment

@Generated(GenerationTime.INSERT) did the trick for me. Even works with regular save(). Thanks

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.