在JPA中设置列的默认值。

时间:2023-02-05 17:56:34

Is it possible to set a default value for columns in JPA, and if, how is it done using annotations?

是否可以为JPA中的列设置默认值,如果,如何使用注释完成?

18 个解决方案

#1


181  

Actually it is possible in JPA, although a little bit of a hack using the columnDefinition property of the @Column annotation, for example:

实际上,在JPA中是可能的,尽管使用@Column注释的columnDefinition属性进行了一些黑客攻击,例如:

@Column(name="Price", columnDefinition="Decimal(10,2) default '100.00'")

#2


232  

You can do the following:

你可以这样做:

@Column(name="price")
private double price = 0.0;

There! You've just used zero as the default value.

在那里!你只使用了0作为默认值。

Note this will serve you if you're only accessing the database from this application. If other applications also use the database, then you should make this check from the database using Cameron's columnDefinition annotation attribute, or some other way.

注意,如果您只是从这个应用程序访问数据库,那么这将为您提供服务。如果其他应用程序也使用数据库,那么您应该使用Cameron的columnDefinition注释属性或其他方法从数据库中进行此检查。

#3


81  

another approach is using javax.persistence.PrePersist

另一种方法是使用javax.persistence.PrePersist。

@PrePersist
void preInsert() {
   if (this.createdTime == null)
       this.createdTime = new Date();
}

#4


16  

In 2017, JPA still has only @Column(columnDefinition='...') to which you put the literal SQL definition of the column. Which is quite unflexible and forces you to also declare the other aspects like type, short-circuiting the JPA implementation's view on that matter.

在2017年,JPA仍然只有@Column(columnDefinition='…'),将列的文本SQL定义放入其中。这是相当不灵活的,并迫使您声明其他方面,如类型,使JPA实现对该问题的视图发生了缩短。

Hibernate though, has this:

然而,Hibernate这样的:

@Column(length = 4096, nullable = false)
@org.hibernate.annotations.ColumnDefault("")
private String description;

Identifies the DEFAULT value to apply to the associated column via DDL.

标识通过DDL应用于关联列的默认值。

Hibernate 4.3 docs (4.3 to show it's been here for quite some time)
Hibernate manual on Default value for database column

Hibernate 4.3文档(4.3显示它已经存在了很长一段时间)Hibernate的默认值为数据库列。

Two notes to that:

两个笔记:

1) Don't be afraid of going non-standard. Working as a JBoss developer, I've seen quite some specification processes. The specification is basically the baseline that the big players in given field are willing to commit to support for the next decade or so. It's true for security, for messaging, ORM is no difference (although JPA covers quite a lot). My experience as a developer is that in a complex application, sooner or later you will need a non-standard API anyway. And @ColumnDefault is an example when it outweigts the negatives of the standard solution.

1)不要害怕进入非标准状态。作为JBoss开发人员,我已经看到了相当多的规范过程。该规范基本上是在给定领域内的大玩家愿意承诺支持未来十年左右的基线。对于安全性而言,对于消息传递来说,ORM是没有区别的(尽管JPA包含很多内容)。作为一名开发人员,我的经验是,在一个复杂的应用程序中,迟早你会需要一个非标准的API。而@ColumnDefault是一个例子,当它超过标准解决方案的缺点时。

2) It's nice how everyone waves @PrePersist or constructor member initialization. But that's NOT the same. How about bulk SQL updates? How about statements that don't set the column? DEFAULT has it's role and that's not substitutable by initializing Java class member.

2)很好,每个人都可以使用@PrePersist或构造函数成员初始化。但这是不一样的。批量SQL更新呢?那些不设置列的语句呢?默认情况下,它是角色,它不是通过初始化Java类成员来替代的。

#5


13  

JPA doesn't support that and it would be useful if it did. Using columnDefinition is DB-specific and not acceptable in many cases. setting a default in the class is not enough when you retrieve a record having null values (which typically happens when you re-run old DBUnit tests). What I do is this:

JPA不支持这一点,如果它做到了,将会很有用。在许多情况下,使用columnDefinition是特定于dba的,而且是不可接受的。当您检索具有空值的记录时,在类中设置默认值是不够的(当您重新运行旧的DBUnit测试时,这通常会发生)。我要做的是:

public class MyObject
{
    int attrib = 0;

    /** Default is 0 */
    @Column ( nullable = true )
    public int getAttrib()

    /** Falls to default = 0 when null */
    public void setAttrib ( Integer attrib ) {
       this.attrib = attrib == null ? 0 : attrib;
    }
}

Java auto-boxing helps a lot in that.

Java自动装箱在这方面有很大帮助。

#6


8  

Seeing as I stumbled upon this from Google while trying to solve the very same problem, I'm just gonna throw in the solution I cooked up in case someone finds it useful.

当我从谷歌发现这个问题的时候,我试图解决同样的问题,我只是想把我做的解决方案扔进去,以防有人发现它有用。

From my point of view there's really only 1 solutions to this problem -- @PrePersist. If you do it in @PrePersist, you gotta check if the value's been set already though.

从我的观点来看,这个问题只有一个解决方案——@PrePersist。如果您在@PrePersist中执行它,那么您必须检查该值是否已经设置好了。

#7


6  

@Column(columnDefinition="tinyint(1) default 1")

I just tested the issue. It works just fine. Thanks for the hint.

我刚刚测试了这个问题。它工作得很好。谢谢你的提示。


About the comments:

关于的评论:

@Column(name="price") 
private double price = 0.0;

This one doesn't set the default column value in the database (of course).

这一项没有设置数据库中的默认列值(当然)。

#8


6  

I use columnDefinition and it works very good

我用的是columnDefinition,它很好用。

@Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

private Date createdDate;

#9


6  

You can't do this with the column annotation. I think the only way is to set the default value when a object is created. Maybe the default constructor would be the right place to do that.

你不能用列注释来做这个。我认为唯一的方法是在创建对象时设置默认值。也许默认构造函数是正确的。

#10


5  

In my case, I modified hibernate-core source code, well, to introduce a new annotation @DefaultValue:

在我的例子中,我修改了hibernate-core源代码,好了,引入了一个新的注解@DefaultValue:

commit 34199cba96b6b1dc42d0d19c066bd4d119b553d5
Author: Lenik <xjl at 99jsj.com>
Date:   Wed Dec 21 13:28:33 2011 +0800

    Add default-value ddl support with annotation @DefaultValue.

diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DefaultValue.java b/hibernate-core/src/main/java/org/hibernate/annotations/DefaultValue.java
new file mode 100644
index 0000000..b3e605e
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/DefaultValue.java
@@ -0,0 +1,35 @@
+package org.hibernate.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+
+/**
+ * Specify a default value for the column.
+ *
+ * This is used to generate the auto DDL.
+ *
+ * WARNING: This is not part of JPA 2.0 specification.
+ *
+ * @author 谢继雷
+ */
+@java.lang.annotation.Target({ FIELD, METHOD })
+@Retention(RUNTIME)
+public @interface DefaultValue {
+
+    /**
+     * The default value sql fragment.
+     *
+     * For string values, you need to quote the value like 'foo'.
+     *
+     * Because different database implementation may use different 
+     * quoting format, so this is not portable. But for simple values
+     * like number and strings, this is generally enough for use.
+     */
+    String value();
+
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java
index b289b1e..ac57f1a 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java
@@ -29,6 +29,7 @@ import org.hibernate.AnnotationException;
 import org.hibernate.AssertionFailure;
 import org.hibernate.annotations.ColumnTransformer;
 import org.hibernate.annotations.ColumnTransformers;
+import org.hibernate.annotations.DefaultValue;
 import org.hibernate.annotations.common.reflection.XProperty;
 import org.hibernate.cfg.annotations.Nullability;
 import org.hibernate.mapping.Column;
@@ -65,6 +66,7 @@ public class Ejb3Column {
    private String propertyName;
    private boolean unique;
    private boolean nullable = true;
+   private String defaultValue;
    private String formulaString;
    private Formula formula;
    private Table table;
@@ -175,7 +177,15 @@ public class Ejb3Column {
        return mappingColumn.isNullable();
    }

-   public Ejb3Column() {
+   public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    public Ejb3Column() {
    }

    public void bind() {
@@ -186,7 +196,7 @@ public class Ejb3Column {
        }
        else {
            initMappingColumn(
-                   logicalColumnName, propertyName, length, precision, scale, nullable, sqlType, unique, true
+                   logicalColumnName, propertyName, length, precision, scale, nullable, sqlType, unique, defaultValue, true
            );
            log.debug( "Binding column: " + toString());
        }
@@ -201,6 +211,7 @@ public class Ejb3Column {
            boolean nullable,
            String sqlType,
            boolean unique,
+           String defaultValue,
            boolean applyNamingStrategy) {
        if ( StringHelper.isNotEmpty( formulaString ) ) {
            this.formula = new Formula();
@@ -217,6 +228,7 @@ public class Ejb3Column {
            this.mappingColumn.setNullable( nullable );
            this.mappingColumn.setSqlType( sqlType );
            this.mappingColumn.setUnique( unique );
+           this.mappingColumn.setDefaultValue(defaultValue);

            if(writeExpression != null && !writeExpression.matches("[^?]*\\?[^?]*")) {
                throw new AnnotationException(
@@ -454,6 +466,11 @@ public class Ejb3Column {
                    else {
                        column.setLogicalColumnName( columnName );
                    }
+                   DefaultValue _defaultValue = inferredData.getProperty().getAnnotation(DefaultValue.class);
+                   if (_defaultValue != null) {
+                       String defaultValue = _defaultValue.value();
+                       column.setDefaultValue(defaultValue);
+                   }

                    column.setPropertyName(
                            BinderHelper.getRelativePath( propertyHolder, inferredData.getPropertyName() )
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
index e57636a..3d871f7 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
@@ -423,6 +424,7 @@ public class Ejb3JoinColumn extends Ejb3Column {
                getMappingColumn() != null ? getMappingColumn().isNullable() : false,
                referencedColumn.getSqlType(),
                getMappingColumn() != null ? getMappingColumn().isUnique() : false,
+               null, // default-value
                false
        );
        linkWithValue( value );
@@ -502,6 +504,7 @@ public class Ejb3JoinColumn extends Ejb3Column {
                getMappingColumn().isNullable(),
                column.getSqlType(),
                getMappingColumn().isUnique(),
+               null, // default-value
                false //We do copy no strategy here
        );
        linkWithValue( value );

Well, this is a hibernate-only solution.

这是一个冬眠的解决办法。

#11


5  

you can use the java reflect api:

您可以使用java反射api:

    @PrePersist
    void preInsert() {
       PrePersistUtil.pre(this);
    }

This is common:

这是很常见的:

    public class PrePersistUtil {

        private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


        public static void pre(Object object){
            try {
                Field[] fields = object.getClass().getDeclaredFields();
                for(Field field : fields){
                    field.setAccessible(true);
                    if (field.getType().getName().equals("java.lang.Long")
                            && field.get(object) == null){
                        field.set(object,0L);
                    }else if    (field.getType().getName().equals("java.lang.String")
                            && field.get(object) == null){
                        field.set(object,"");
                    }else if (field.getType().getName().equals("java.util.Date")
                            && field.get(object) == null){
                        field.set(object,sdf.parse("1900-01-01"));
                    }else if (field.getType().getName().equals("java.lang.Double")
                            && field.get(object) == null){
                        field.set(object,0.0d);
                    }else if (field.getType().getName().equals("java.lang.Integer")
                            && field.get(object) == null){
                        field.set(object,0);
                    }else if (field.getType().getName().equals("java.lang.Float")
                            && field.get(object) == null){
                        field.set(object,0.0f);
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

#12


2  

Neither JPA nor Hibernate annotations support the notion of a default column value. As a workaround to this limitation, set all default values just before you invoke a Hibernate save() or update() on the session. This closely as possible (short of Hibernate setting the default values) mimics the behaviour of the database which sets default values when it saves a row in a table.

JPA和Hibernate注释都不支持默认列值的概念。作为对这个限制的解决方案,在调用Hibernate save()或更新()之前,设置所有默认值。这与数据库的行为密切相关(Hibernate设置默认值)模仿数据库的行为,当它在表中保存一行时设置默认值。

Unlike setting the default values in the model class as this alternative answer suggests, this approach also ensures that criteria queries that use an Example object as a prototype for the search will continue to work as before. When you set the default value of a nullable attribute (one that has a non-primitive type) in a model class, a Hibernate query-by-example will no longer ignore the associated column where previously it would ignore it because it was null.

与在模型类中设置默认值不同,此方法还可以确保使用示例对象作为搜索原型的criteria查询将继续像以前一样工作。当您在模型类中设置一个可空属性(具有非基本类型的属性)的默认值时,一个Hibernate查询的示例将不再忽略相关的列,因为之前它将忽略它,因为它是null。

#13


1  

This isn't possible in JPA.

这在JPA中是不可能的。

Here's what you can do with the Column annotation: http://java.sun.com/javaee/5/docs/api/javax/persistence/Column.html

下面是您可以用列注释做的事情:http://java.sun.com/javaee/5/docs/api/javax/persistence/Column.html。

#14


1  

If you're using a double, you can use the following:

如果您使用的是double,您可以使用以下内容:

@Column(columnDefinition="double precision default '96'")

private Double grolsh;

Yes it's db specific.

是的这是db具体。

#15


1  

@PrePersist
void preInsert() {
    if (this.dateOfConsent == null)
        this.dateOfConsent = LocalDateTime.now();
    if(this.consentExpiry==null)
        this.consentExpiry = this.dateOfConsent.plusMonths(3);
}

In my case due to the field being LocalDateTime i used this, it is recommended due to vendor independence

在我的例子中,由于字段是LocalDateTime,我使用了这个,建议由于厂商独立性。

#16


0  

You can define the default value in the database designer, or when you create the table. For instance in SQL Server you can set the default vault of a Date field to (getDate()). Use insertable=false as mentioned in your column definition. JPA will not specify that column on inserts and the database will generate the value for you.

您可以在数据库设计器中定义默认值,也可以在创建表时定义它。例如,在SQL Server中,可以设置日期字段的默认保险库(getDate())。在列定义中使用insertable=false。JPA不会指定插入的列,而数据库将为您生成值。

#17


0  

  1. @Column(columnDefinition='...') doesn't work when you set the default constraint in database while inserting the data.
  2. 当在数据库中设置默认约束时,在插入数据时,该列(columnDefinition='…')不起作用。
  3. You need to make insertable = false and remove columnDefinition='...' from annotation, then database will automatically insert the default value from the database.
  4. 您需要使insertable = false并删除columnDefinition='…从注释中,数据库将自动从数据库中插入默认值。
  5. E.g. when you set varchar gender is male by default in database.
  6. 在数据库中默认设置varchar性别是男性。
  7. You just need to add insertable = false in Hibernate/JPA, it will work.
  8. 您只需要在Hibernate/JPA中添加insertable = false,就可以了。

#18


-2  

You need to insertable=false in you @Column annotation. JPA will ignore then that column while inserting in the database and the default value will be used.

您需要在@Column注释中插入=false。JPA在插入数据库时将忽略该列,并将使用默认值。

See this link : http://mariemjabloun.blogspot.com/2014/03/resolved-set-database-default-value-in.html

查看此链接:http://mariemjabloun.blogspot.com/2014/03/resolved-set-database-default-value-in.html。

#1


181  

Actually it is possible in JPA, although a little bit of a hack using the columnDefinition property of the @Column annotation, for example:

实际上,在JPA中是可能的,尽管使用@Column注释的columnDefinition属性进行了一些黑客攻击,例如:

@Column(name="Price", columnDefinition="Decimal(10,2) default '100.00'")

#2


232  

You can do the following:

你可以这样做:

@Column(name="price")
private double price = 0.0;

There! You've just used zero as the default value.

在那里!你只使用了0作为默认值。

Note this will serve you if you're only accessing the database from this application. If other applications also use the database, then you should make this check from the database using Cameron's columnDefinition annotation attribute, or some other way.

注意,如果您只是从这个应用程序访问数据库,那么这将为您提供服务。如果其他应用程序也使用数据库,那么您应该使用Cameron的columnDefinition注释属性或其他方法从数据库中进行此检查。

#3


81  

another approach is using javax.persistence.PrePersist

另一种方法是使用javax.persistence.PrePersist。

@PrePersist
void preInsert() {
   if (this.createdTime == null)
       this.createdTime = new Date();
}

#4


16  

In 2017, JPA still has only @Column(columnDefinition='...') to which you put the literal SQL definition of the column. Which is quite unflexible and forces you to also declare the other aspects like type, short-circuiting the JPA implementation's view on that matter.

在2017年,JPA仍然只有@Column(columnDefinition='…'),将列的文本SQL定义放入其中。这是相当不灵活的,并迫使您声明其他方面,如类型,使JPA实现对该问题的视图发生了缩短。

Hibernate though, has this:

然而,Hibernate这样的:

@Column(length = 4096, nullable = false)
@org.hibernate.annotations.ColumnDefault("")
private String description;

Identifies the DEFAULT value to apply to the associated column via DDL.

标识通过DDL应用于关联列的默认值。

Hibernate 4.3 docs (4.3 to show it's been here for quite some time)
Hibernate manual on Default value for database column

Hibernate 4.3文档(4.3显示它已经存在了很长一段时间)Hibernate的默认值为数据库列。

Two notes to that:

两个笔记:

1) Don't be afraid of going non-standard. Working as a JBoss developer, I've seen quite some specification processes. The specification is basically the baseline that the big players in given field are willing to commit to support for the next decade or so. It's true for security, for messaging, ORM is no difference (although JPA covers quite a lot). My experience as a developer is that in a complex application, sooner or later you will need a non-standard API anyway. And @ColumnDefault is an example when it outweigts the negatives of the standard solution.

1)不要害怕进入非标准状态。作为JBoss开发人员,我已经看到了相当多的规范过程。该规范基本上是在给定领域内的大玩家愿意承诺支持未来十年左右的基线。对于安全性而言,对于消息传递来说,ORM是没有区别的(尽管JPA包含很多内容)。作为一名开发人员,我的经验是,在一个复杂的应用程序中,迟早你会需要一个非标准的API。而@ColumnDefault是一个例子,当它超过标准解决方案的缺点时。

2) It's nice how everyone waves @PrePersist or constructor member initialization. But that's NOT the same. How about bulk SQL updates? How about statements that don't set the column? DEFAULT has it's role and that's not substitutable by initializing Java class member.

2)很好,每个人都可以使用@PrePersist或构造函数成员初始化。但这是不一样的。批量SQL更新呢?那些不设置列的语句呢?默认情况下,它是角色,它不是通过初始化Java类成员来替代的。

#5


13  

JPA doesn't support that and it would be useful if it did. Using columnDefinition is DB-specific and not acceptable in many cases. setting a default in the class is not enough when you retrieve a record having null values (which typically happens when you re-run old DBUnit tests). What I do is this:

JPA不支持这一点,如果它做到了,将会很有用。在许多情况下,使用columnDefinition是特定于dba的,而且是不可接受的。当您检索具有空值的记录时,在类中设置默认值是不够的(当您重新运行旧的DBUnit测试时,这通常会发生)。我要做的是:

public class MyObject
{
    int attrib = 0;

    /** Default is 0 */
    @Column ( nullable = true )
    public int getAttrib()

    /** Falls to default = 0 when null */
    public void setAttrib ( Integer attrib ) {
       this.attrib = attrib == null ? 0 : attrib;
    }
}

Java auto-boxing helps a lot in that.

Java自动装箱在这方面有很大帮助。

#6


8  

Seeing as I stumbled upon this from Google while trying to solve the very same problem, I'm just gonna throw in the solution I cooked up in case someone finds it useful.

当我从谷歌发现这个问题的时候,我试图解决同样的问题,我只是想把我做的解决方案扔进去,以防有人发现它有用。

From my point of view there's really only 1 solutions to this problem -- @PrePersist. If you do it in @PrePersist, you gotta check if the value's been set already though.

从我的观点来看,这个问题只有一个解决方案——@PrePersist。如果您在@PrePersist中执行它,那么您必须检查该值是否已经设置好了。

#7


6  

@Column(columnDefinition="tinyint(1) default 1")

I just tested the issue. It works just fine. Thanks for the hint.

我刚刚测试了这个问题。它工作得很好。谢谢你的提示。


About the comments:

关于的评论:

@Column(name="price") 
private double price = 0.0;

This one doesn't set the default column value in the database (of course).

这一项没有设置数据库中的默认列值(当然)。

#8


6  

I use columnDefinition and it works very good

我用的是columnDefinition,它很好用。

@Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

private Date createdDate;

#9


6  

You can't do this with the column annotation. I think the only way is to set the default value when a object is created. Maybe the default constructor would be the right place to do that.

你不能用列注释来做这个。我认为唯一的方法是在创建对象时设置默认值。也许默认构造函数是正确的。

#10


5  

In my case, I modified hibernate-core source code, well, to introduce a new annotation @DefaultValue:

在我的例子中,我修改了hibernate-core源代码,好了,引入了一个新的注解@DefaultValue:

commit 34199cba96b6b1dc42d0d19c066bd4d119b553d5
Author: Lenik <xjl at 99jsj.com>
Date:   Wed Dec 21 13:28:33 2011 +0800

    Add default-value ddl support with annotation @DefaultValue.

diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DefaultValue.java b/hibernate-core/src/main/java/org/hibernate/annotations/DefaultValue.java
new file mode 100644
index 0000000..b3e605e
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/DefaultValue.java
@@ -0,0 +1,35 @@
+package org.hibernate.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+
+/**
+ * Specify a default value for the column.
+ *
+ * This is used to generate the auto DDL.
+ *
+ * WARNING: This is not part of JPA 2.0 specification.
+ *
+ * @author 谢继雷
+ */
+@java.lang.annotation.Target({ FIELD, METHOD })
+@Retention(RUNTIME)
+public @interface DefaultValue {
+
+    /**
+     * The default value sql fragment.
+     *
+     * For string values, you need to quote the value like 'foo'.
+     *
+     * Because different database implementation may use different 
+     * quoting format, so this is not portable. But for simple values
+     * like number and strings, this is generally enough for use.
+     */
+    String value();
+
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java
index b289b1e..ac57f1a 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java
@@ -29,6 +29,7 @@ import org.hibernate.AnnotationException;
 import org.hibernate.AssertionFailure;
 import org.hibernate.annotations.ColumnTransformer;
 import org.hibernate.annotations.ColumnTransformers;
+import org.hibernate.annotations.DefaultValue;
 import org.hibernate.annotations.common.reflection.XProperty;
 import org.hibernate.cfg.annotations.Nullability;
 import org.hibernate.mapping.Column;
@@ -65,6 +66,7 @@ public class Ejb3Column {
    private String propertyName;
    private boolean unique;
    private boolean nullable = true;
+   private String defaultValue;
    private String formulaString;
    private Formula formula;
    private Table table;
@@ -175,7 +177,15 @@ public class Ejb3Column {
        return mappingColumn.isNullable();
    }

-   public Ejb3Column() {
+   public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    public Ejb3Column() {
    }

    public void bind() {
@@ -186,7 +196,7 @@ public class Ejb3Column {
        }
        else {
            initMappingColumn(
-                   logicalColumnName, propertyName, length, precision, scale, nullable, sqlType, unique, true
+                   logicalColumnName, propertyName, length, precision, scale, nullable, sqlType, unique, defaultValue, true
            );
            log.debug( "Binding column: " + toString());
        }
@@ -201,6 +211,7 @@ public class Ejb3Column {
            boolean nullable,
            String sqlType,
            boolean unique,
+           String defaultValue,
            boolean applyNamingStrategy) {
        if ( StringHelper.isNotEmpty( formulaString ) ) {
            this.formula = new Formula();
@@ -217,6 +228,7 @@ public class Ejb3Column {
            this.mappingColumn.setNullable( nullable );
            this.mappingColumn.setSqlType( sqlType );
            this.mappingColumn.setUnique( unique );
+           this.mappingColumn.setDefaultValue(defaultValue);

            if(writeExpression != null && !writeExpression.matches("[^?]*\\?[^?]*")) {
                throw new AnnotationException(
@@ -454,6 +466,11 @@ public class Ejb3Column {
                    else {
                        column.setLogicalColumnName( columnName );
                    }
+                   DefaultValue _defaultValue = inferredData.getProperty().getAnnotation(DefaultValue.class);
+                   if (_defaultValue != null) {
+                       String defaultValue = _defaultValue.value();
+                       column.setDefaultValue(defaultValue);
+                   }

                    column.setPropertyName(
                            BinderHelper.getRelativePath( propertyHolder, inferredData.getPropertyName() )
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
index e57636a..3d871f7 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
@@ -423,6 +424,7 @@ public class Ejb3JoinColumn extends Ejb3Column {
                getMappingColumn() != null ? getMappingColumn().isNullable() : false,
                referencedColumn.getSqlType(),
                getMappingColumn() != null ? getMappingColumn().isUnique() : false,
+               null, // default-value
                false
        );
        linkWithValue( value );
@@ -502,6 +504,7 @@ public class Ejb3JoinColumn extends Ejb3Column {
                getMappingColumn().isNullable(),
                column.getSqlType(),
                getMappingColumn().isUnique(),
+               null, // default-value
                false //We do copy no strategy here
        );
        linkWithValue( value );

Well, this is a hibernate-only solution.

这是一个冬眠的解决办法。

#11


5  

you can use the java reflect api:

您可以使用java反射api:

    @PrePersist
    void preInsert() {
       PrePersistUtil.pre(this);
    }

This is common:

这是很常见的:

    public class PrePersistUtil {

        private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


        public static void pre(Object object){
            try {
                Field[] fields = object.getClass().getDeclaredFields();
                for(Field field : fields){
                    field.setAccessible(true);
                    if (field.getType().getName().equals("java.lang.Long")
                            && field.get(object) == null){
                        field.set(object,0L);
                    }else if    (field.getType().getName().equals("java.lang.String")
                            && field.get(object) == null){
                        field.set(object,"");
                    }else if (field.getType().getName().equals("java.util.Date")
                            && field.get(object) == null){
                        field.set(object,sdf.parse("1900-01-01"));
                    }else if (field.getType().getName().equals("java.lang.Double")
                            && field.get(object) == null){
                        field.set(object,0.0d);
                    }else if (field.getType().getName().equals("java.lang.Integer")
                            && field.get(object) == null){
                        field.set(object,0);
                    }else if (field.getType().getName().equals("java.lang.Float")
                            && field.get(object) == null){
                        field.set(object,0.0f);
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

#12


2  

Neither JPA nor Hibernate annotations support the notion of a default column value. As a workaround to this limitation, set all default values just before you invoke a Hibernate save() or update() on the session. This closely as possible (short of Hibernate setting the default values) mimics the behaviour of the database which sets default values when it saves a row in a table.

JPA和Hibernate注释都不支持默认列值的概念。作为对这个限制的解决方案,在调用Hibernate save()或更新()之前,设置所有默认值。这与数据库的行为密切相关(Hibernate设置默认值)模仿数据库的行为,当它在表中保存一行时设置默认值。

Unlike setting the default values in the model class as this alternative answer suggests, this approach also ensures that criteria queries that use an Example object as a prototype for the search will continue to work as before. When you set the default value of a nullable attribute (one that has a non-primitive type) in a model class, a Hibernate query-by-example will no longer ignore the associated column where previously it would ignore it because it was null.

与在模型类中设置默认值不同,此方法还可以确保使用示例对象作为搜索原型的criteria查询将继续像以前一样工作。当您在模型类中设置一个可空属性(具有非基本类型的属性)的默认值时,一个Hibernate查询的示例将不再忽略相关的列,因为之前它将忽略它,因为它是null。

#13


1  

This isn't possible in JPA.

这在JPA中是不可能的。

Here's what you can do with the Column annotation: http://java.sun.com/javaee/5/docs/api/javax/persistence/Column.html

下面是您可以用列注释做的事情:http://java.sun.com/javaee/5/docs/api/javax/persistence/Column.html。

#14


1  

If you're using a double, you can use the following:

如果您使用的是double,您可以使用以下内容:

@Column(columnDefinition="double precision default '96'")

private Double grolsh;

Yes it's db specific.

是的这是db具体。

#15


1  

@PrePersist
void preInsert() {
    if (this.dateOfConsent == null)
        this.dateOfConsent = LocalDateTime.now();
    if(this.consentExpiry==null)
        this.consentExpiry = this.dateOfConsent.plusMonths(3);
}

In my case due to the field being LocalDateTime i used this, it is recommended due to vendor independence

在我的例子中,由于字段是LocalDateTime,我使用了这个,建议由于厂商独立性。

#16


0  

You can define the default value in the database designer, or when you create the table. For instance in SQL Server you can set the default vault of a Date field to (getDate()). Use insertable=false as mentioned in your column definition. JPA will not specify that column on inserts and the database will generate the value for you.

您可以在数据库设计器中定义默认值,也可以在创建表时定义它。例如,在SQL Server中,可以设置日期字段的默认保险库(getDate())。在列定义中使用insertable=false。JPA不会指定插入的列,而数据库将为您生成值。

#17


0  

  1. @Column(columnDefinition='...') doesn't work when you set the default constraint in database while inserting the data.
  2. 当在数据库中设置默认约束时,在插入数据时,该列(columnDefinition='…')不起作用。
  3. You need to make insertable = false and remove columnDefinition='...' from annotation, then database will automatically insert the default value from the database.
  4. 您需要使insertable = false并删除columnDefinition='…从注释中,数据库将自动从数据库中插入默认值。
  5. E.g. when you set varchar gender is male by default in database.
  6. 在数据库中默认设置varchar性别是男性。
  7. You just need to add insertable = false in Hibernate/JPA, it will work.
  8. 您只需要在Hibernate/JPA中添加insertable = false,就可以了。

#18


-2  

You need to insertable=false in you @Column annotation. JPA will ignore then that column while inserting in the database and the default value will be used.

您需要在@Column注释中插入=false。JPA在插入数据库时将忽略该列,并将使用默认值。

See this link : http://mariemjabloun.blogspot.com/2014/03/resolved-set-database-default-value-in.html

查看此链接:http://mariemjabloun.blogspot.com/2014/03/resolved-set-database-default-value-in.html。