175

How do I set a default value in Hibernate field?

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
Dejell
  • 13,947
  • 40
  • 146
  • 229
  • 3
    Are you using the XML config file or annotations? – Bruno Jun 24 '10 at 13:23
  • 2
    The answer below only give JPA solutions, which is correct but .for an Hibernate solution see http://stackoverflow.com/questions/28107554/define-default-column-value-with-annotations-in-hibernate you have to use `@ColumnDefault` – pdem Sep 20 '16 at 07:25

18 Answers18

215

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;

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
Petar Minchev
  • 46,889
  • 11
  • 103
  • 119
  • 6
    With annotations: @org.hibernate.annotations.Entity(dynamicInsert = true) – homaxto Mar 14 '11 at 10:04
  • 12
    Currently `org.hibernate.annotations.Entity` is deprecated. `@DynamicInsert` annotation should be used instead. – jannis Jun 14 '16 at 19:07
  • 3
    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. – pdem Sep 20 '16 at 07:30
  • 1
    @DynamicInsert needs to be added on the database pojo class. – Reaz Murshed Apr 27 '17 at 08:26
  • 6
    I'd recommend using @ColumnDefault instead of columnDefinition as it is more database independent https://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/annotations/ColumnDefault.html – jalsh Jun 21 '18 at 07:44
  • 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 – pikimota Jul 16 '18 at 09:26
61

Use hibernate annotation.

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

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

Community
  • 1
  • 1
Mazen Embaby
  • 1,255
  • 11
  • 18
  • 1
    Thank you, it works. But I had to recreate the table. – Yamashiro Rion May 13 '19 at 09:59
  • 6
    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. – judos Jan 23 '20 at 13:10
  • 1
    Note: `@ColumnDefault` is only useful when you use `hibernate.hbm2ddl.auto` to let hibernate to auto create/update your DB schema. If you do not use such auto-schema generation feature, it will not have any effect. – jumping_monkey Sep 02 '22 at 04:29
  • In addition this solution is portable: MySQL, pgSQL – fdaugan Jan 23 '23 at 09:49
39

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.

donquih0te
  • 597
  • 3
  • 22
dbricman
  • 488
  • 5
  • 6
  • Given that `setMyProperty` is not used by your example. Why do you include it? – EndermanAPM Dec 28 '17 at 14:27
  • 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. – dbricman Feb 27 '18 at 15:36
32

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.

Tim Hoolihan
  • 12,316
  • 3
  • 41
  • 54
19

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;
Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
  • Perfect, using @Generated worked for me. But what would be the difference with @GeneratedValue? – Braian Coronel Oct 18 '20 at 03:47
  • 1
    `@GeneratedValue` can only be used for entity identifiers. – Vlad Mihalcea Oct 18 '20 at 04:11
  • `@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. – Braian Coronel Oct 18 '20 at 22:23
  • Use `@MapsId`, as explained in [this article](https://vladmihalcea.com/the-best-way-to-map-a-onetoone-association-with-jpa-and-hibernate/). – Vlad Mihalcea Oct 19 '20 at 05:53
  • In the end I solved it using `@DynamicInsert` in the entity so that the DBMS value precedes – Braian Coronel Oct 22 '20 at 03:30
  • 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 Feb 01 '21 at 09:47
  • @VladMihalcea Is an explicit flush required to get the current default values in current transactional context? – JavaLearner Feb 02 '21 at 06:21
8

If you want to do it in database:

Set the default value in database (sql server sample):

ALTER TABLE [TABLE_NAME] ADD  CONSTRAINT [CONSTRAINT_NAME]  DEFAULT (newid()) FOR [COLUMN_NAME]

Mapping hibernate file:

    <hibernate-mapping ....
    ...    
    <property name="fieldName" column="columnName" type="Guid" access="field" not-null="false"  insert="false" update="false"  />
    ...

See, the key is insert="false" update="false"

CSA
  • 393
  • 4
  • 10
  • There's a problem for Oracle: If the property is not null, its value STILL the default value. Not the actual value. – youngzy Jan 19 '16 at 08:18
6

One solution is to have your getter check to see if whatever value you are working with is null (or whatever its non-initialized state would be) and if it's equal to that, just return your default value:

public String getStringValue(){
     return (this.stringValue == null) ? "Default" : stringValue;
}
Ian Dallas
  • 12,451
  • 19
  • 58
  • 82
  • 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? – Eric Francis Jan 06 '16 at 15:41
  • 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. – Velmurugan A Oct 21 '21 at 08:17
5

Use @ColumnDefault() annotation. This is hibernate only though.

T3rm1
  • 2,299
  • 5
  • 34
  • 51
4

I searched for this and found many answers to default value for column.If you want to use default value defined in SQL Table then in @Column Annotation use "insertable = false". insertable

@Column(name = columnName, length = lengthOfColumn, insertable = false)

If you are using columnDefination it @Column annotation may be it won't work as it is Database dependent.

4

Working with Oracle, I was trying to insert a default value for an Enum

I found the following to work the best.

@Column(nullable = false)
@Enumerated(EnumType.STRING)
private EnumType myProperty = EnumType.DEFAULT_VALUE;
andorov
  • 4,197
  • 3
  • 39
  • 52
Bojan Petkovic
  • 2,406
  • 15
  • 26
3

To use default value from any column of table. then you must need to define @DynamicInsert as true or else you just define @DynamicInsert. Because hibernate takes by default as a true. Consider as the given example:

@AllArgsConstructor
@Table(name = "core_contact")
@DynamicInsert
public class Contact implements Serializable {

    @Column(name = "status", columnDefinition = "int default 100")
    private Long status;

}
donquih0te
  • 597
  • 3
  • 22
2

You can use the java class constructor to set the default values. For example:

public class Entity implements Serializable{
 private Double field1
 private Integer field2;
 private T fieldN;

 public Entity(){
  this.field1=0.0;
  this.field2=0;
  ...
  this.fieldN= <your default value>
 }

 //Setters and Getters
...

}
IKavanagh
  • 6,089
  • 11
  • 42
  • 47
2

I tried it. when i did that

@Column(name = "is_sale", columnDefinition = "default false")
private boolean isSale = false;

enter image description here

he did not add. And when I did

@Column(name = "is_sale", columnDefinition = "bool default false")
 private boolean isSale = false;

in this case Hibernate generated such sql

alter table if exists customer_product add column is_sale bool default false

enter image description here and it helped me

1
<property name="age" type="integer">
<column name="age" not-null="false" default="null" />
</property>
uı6ʎɹnɯ ꞁəıuɐp
  • 3,431
  • 3
  • 40
  • 49
  • 6
    Mind to [explain your solution](http://stackoverflow.com/help/how-to-answer) a bit? You might want to read [How Do I Write A Good Answer](http://stackoverflow.com/help/how-to-answer). – Markus W Mahlberg Apr 27 '15 at 12:31
1

i'am working with hibernate 5 and postgres, and this worked form me.

@Column(name = "ACCOUNT_TYPE", ***nullable***=false, columnDefinition="varchar2 default 'END_USER'")
@Enumerated(EnumType.STRING)
private AccountType accountType;
donquih0te
  • 597
  • 3
  • 22
Ala Messaoudi
  • 366
  • 4
  • 12
0

If you want to set default value in terms of database, just set @Column( columnDefinition = "int default 1")

But if what you intend is to set a default value in your java app you can set it on your class attribute like this: private Integer attribute = 1;

0

Suppose we have an entity which contains a sub-entity.

Using insertable = false, updatable = false on the entity prevents the entity from creating new sub-entities and preceding the default DBMS value. But the problem with this is that we are obliged to always use the default value or if we need the entity to contain another sub-entity that is not the default, we must try to change these annotations at runtime to insertable = true, updatable = true, so it doesn't seem like a good path.

Inside the sub-entity if it makes more sense to use in all the columns insertable = false, updatable = false so that no more sub-entities are created regardless of the method we use (with @DynamicInsert it would not be necessary)

Inserting a default value can be done in various ways such as Default entity property value using constructor or setter. Other ways like using JPA with columnDefinition have the drawback that they insert a null by default and the default value of the DBMS does not precede.


Insert default value using DBMS and optional using Hibernate

But using @DynamicInsert we avoid sending a null to the db when we want to insert a sub-entity with its default value, and in turn we allow sub-entities with values other than the default to be inserted.

For inserting, should this entity use dynamic sql generation where only non-null columns get referenced in the prepared sql statement?

Given the following needs:

  • The entity does not have the responsibility of creating new sub-entities.
  • When inserting an entity, the sub-entity is the one that was defined as default in the DBMS.
  • Possibility of creating an entity with a sub-entity which has a UUID other than the default.

DBMS: PostgreSQL | Language: Kotlin

@Entity
@Table(name = "entity")
@DynamicInsert
data class EntityTest(
        @Id @GeneratedValue @Column(name = "entity_uuid") val entityUUID: UUID? = null,

        @OneToOne(cascade = [CascadeType.ALL])
        @JoinColumn(name = "subentity_uuid", referencedColumnName = "subentity_uuid")
        var subentityTest: SubentityTest? = null
) {}

@Entity
@Table(name = "subentity")
data class SubentityTest(
        @Id @GeneratedValue @Column(name = "subentity_uuid", insertable = false, updatable = false) var subentityUUID: UUID? = null,
        @Column(insertable = false, updatable = false) var name: String,
) {
        constructor() : this(name = "")
}

And the value is set by default in the database:

alter table entity alter column subentity_uuid set default 'd87ee95b-06f1-52ab-83ed-5d882ae400e6'::uuid;

GL

Braian Coronel
  • 22,105
  • 4
  • 57
  • 62
0

we can have getter that annotates @Column

all @column should be annotated in getter alone instead of direct variable declaration. by this way, we can resolve it.

    @Column(name = "string_value")
public String getStringValue(){
         return (this.stringValue == null) ? "Default" : stringValue;
    }
Velmurugan A
  • 348
  • 3
  • 7