How to set a default entity property value with Hibernate

305,485

Solution 1

If you want a real database default value, use columnDefinition:

@Column(name = "myColumn", nullable = false, columnDefinition = "int default 100") 

Notice that the string in columnDefinition is database dependent. Also if you choose this option, you have to use dynamic-insert, so Hibernate doesn't include columns with null values on insert. Otherwise talking about default is irrelevant.

But if you don't want database default value, but simply a default value in your Java code, just initialize your variable like that - private Integer myColumn = 100;

Solution 2

Use hibernate annotation.

@ColumnDefault("-1")
private Long clientId;

Recreate the table if it already exists for the changes to take effect.

Solution 3

You can use @PrePersist anotation and set the default value in pre-persist stage.

Something like that:

//... some code
private String myProperty;
//... some code

@PrePersist
public void prePersist() {
    if(myProperty == null) //We set default value in case if the value is not set yet.
        myProperty = "Default value";
}

// property methods
@Column(nullable = false) //restricting Null value on database level.
public String getMyProperty() {
    return myProperty;
}

public void setMyProperty(String myProperty) {
    this.myProperty= myProperty;
}

This method is not depend on database type/version underneath the Hibernate. Default value is set before persisting the mapping object.

Solution 4

what about just setting a default value for the field?

private String _foo = "default";

//property here
public String Foo

if they pass a value, then it will be overwritten, otherwise, you have a default.

Solution 5

Default entity property value

If you want to set a default entity property value, then you can initialize the entity field using the default value.

For instance, you can set the default createdOn entity attribute to the current time, like this:

@Column(
    name = "created_on"
)
private LocalDateTime createdOn = LocalDateTime.now();

Default column value using JPA

If you are generating the DDL schema with JPA and Hibernate, although this is not recommended, you can use the columnDefinition attribute of the JPA @Column annotation, like this:

@Column(
    name = "created_on", 
    columnDefinition = "DATETIME(6) DEFAULT CURRENT_TIMESTAMP"
)
@Generated(GenerationTime.INSERT)
private LocalDateTime createdOn;

The @Generated annotation is needed because we want to instruct Hibernate to reload the entity after the Persistence Context is flushed, otherwise, the database-generated value will not be synchronized with the in-memory entity state.

Instead of using the columnDefinition, you are better off using a tool like Flyway and use DDL incremental migration scripts. That way, you will set the DEFAULT SQL clause in a script, rather than in a JPA annotation.

Default column value using Hibernate

If you are using JPA with Hibernate, then you can also use the @ColumnDefault annotation, like this:

@Column(name = "created_on")
@ColumnDefault(value="CURRENT_TIMESTAMP")
@Generated(GenerationTime.INSERT)
private LocalDateTime createdOn;

Default Date/Time column value using Hibernate

If you are using JPA with Hibernate and want to set the creation timestamp, then you can use the @CreationTimestamp annotation, like this:

@Column(name = "created_on")
@CreationTimestamp
private LocalDateTime createdOn;
Share:
305,485

Related videos on Youtube

Dejell
Author by

Dejell

I like traveling around the world. So far I have been to: USA England Italy Slovania Croatia Jordan South Africa Zimbabwe Botswana France Canada Israel Thailand Switzerland Holland Bulgaria I am going to Vietnam soon

Updated on March 31, 2022

Comments

  • Dejell
    Dejell over 2 years

    How do I set a default value in Hibernate field?

    • Bruno
      Bruno about 14 years
      Are you using the XML config file or annotations?
    • pdem
      pdem almost 8 years
      The answer below only give JPA solutions, which is correct but .for an Hibernate solution see stackoverflow.com/questions/28107554/… you have to use @ColumnDefault
  • homaxto
    homaxto over 13 years
    With annotations: @org.hibernate.annotations.Entity(dynamicInsert = true)
  • Markus W Mahlberg
    Markus W Mahlberg about 9 years
    Mind to explain your solution a bit? You might want to read How Do I Write A Good Answer.
  • Eric Francis
    Eric Francis over 8 years
    I'm using a mapper that calls the setter on my entity object. Is there a downside to using your code snippet on both the getter and the setter?
  • youngzy
    youngzy over 8 years
    There's a problem for Oracle: If the property is not null, its value STILL the default value. Not the actual value.
  • jannis
    jannis about 8 years
    Currently org.hibernate.annotations.Entity is deprecated. @DynamicInsert annotation should be used instead.
  • Janusz Lenar
    Janusz Lenar almost 8 years
    @michali: role of a default value is not preventing from updating the value, is it?
  • pdem
    pdem almost 8 years
    I would not recommend using columnDefinition for this situation, this is not portable from a database to another, and you need to know the specific SQL language of your server.
  • Reaz Murshed
    Reaz Murshed about 7 years
    @DynamicInsert needs to be added on the database pojo class.
  • EndermanAPM
    EndermanAPM over 6 years
    Given that setMyProperty is not used by your example. Why do you include it?
  • dbricman
    dbricman over 6 years
    I just give the example of hibernate annotations for standard java property (private variable with public get/set methods). I noticed and corrected one mistake... String type of set method argumet was missing.
  • jalsh
    jalsh about 6 years
    I'd recommend using @ColumnDefault instead of columnDefinition as it is more database independent docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/…
  • pikimota
    pikimota almost 6 years
    just be aware that depends on hibernate.hbm2ddl.auto hibernate definition. If set to "CREATE" annotation columnDefinition is used only in creating database, notihing changes if your database is already created
  • Michal Filip
    Michal Filip over 5 years
    This works great for columns like "createdAt" where you always want to use the DB default. Thanks!
  • Yamashiro Rion
    Yamashiro Rion about 5 years
    Thank you, it works. But I had to recreate the table.
  • judos
    judos over 4 years
    This should be the real solution, using columnDefinition as proposed by the current answer is a hastle and you have to include the type. The annotation @ColumnDefault is much easier in my opinion.
  • Braian Coronel
    Braian Coronel over 3 years
    Perfect, using @Generated worked for me. But what would be the difference with @GeneratedValue?
  • Vlad Mihalcea
    Vlad Mihalcea over 3 years
    @GeneratedValue can only be used for entity identifiers.
  • Braian Coronel
    Braian Coronel over 3 years
    @GeneratedValue only works for the primary key of the entity and @Generated for primitive values. But what should I use for a sub-entity or foreign key that has annotations like @OneToOne? Because none of the 2 annotations is working for me for that case.
  • Vlad Mihalcea
    Vlad Mihalcea over 3 years
    Use @MapsId, as explained in this article.
  • Braian Coronel
    Braian Coronel over 3 years
    In the end I solved it using @DynamicInsert in the entity so that the DBMS value precedes
  • JavaLearner
    JavaLearner over 3 years
    Using @Generated(GenerationTime.INSERT) throws org.springframework.orm.jpa.JpaSystemException: Lock mode not supported; nested exception is org.hibernate.UnsupportedLockAttemptException: Lock mode not supported when using H2 in memory DB for tests
  • JavaLearner
    JavaLearner over 3 years
    @VladMihalcea Is an explicit flush required to get the current default values in current transactional context?
  • Velmurugan A
    Velmurugan A over 2 years
    Im using spring boot . inside that one entity class i tried like this : > private Long trianglesCount ; @Column(name = "triangles_count") public Long getTrianglesCount() { if(this.trianglesCount == null) return 0L; else return this.trianglesCount; } this not saves 0L by default. it saves null in the db.