Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 设置要由数据库生成的JPA时间戳列?_Java_Jpa_Persistence_Annotations_Timestamp - Fatal编程技术网

Java 设置要由数据库生成的JPA时间戳列?

Java 设置要由数据库生成的JPA时间戳列?,java,jpa,persistence,annotations,timestamp,Java,Jpa,Persistence,Annotations,Timestamp,在我的SQL Server 2000数据库中,我有一个类型为DATETIME的时间戳(在函数中而不是在数据类型中)列,名为lastpothed设置为getdate(),作为其默认值/绑定 我正在使用Netbeans 6.5生成的JPA实体类,并在代码中包含了这些类 @Basic(optional = false) @Column(name = "LastTouched") @Temporal(TemporalType.TIMESTAMP) private Date lastTouched; 但

在我的SQL Server 2000数据库中,我有一个类型为
DATETIME
的时间戳(在函数中而不是在数据类型中)列,名为
lastpothed
设置为
getdate()
,作为其默认值/绑定

我正在使用Netbeans 6.5生成的JPA实体类,并在代码中包含了这些类

@Basic(optional = false)
@Column(name = "LastTouched")
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;
但是,当我尝试将对象放入数据库时

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.generic.Stuff.lastTouched
我尝试将
@Basic
设置为
(optional=true)
,但这引发了一个异常,表示数据库不允许
TIMESTAMP
列的
null
值,而这在设计上是不允许的

ERROR JDBCExceptionReporter - Cannot insert the value NULL into column 'LastTouched', table 'DatabaseName.dbo.Stuff'; column does not allow nulls. INSERT fails.

我以前在纯Hibernate中实现了这一点,但后来我切换到JPA,不知道如何告诉它应该在数据库端生成此列。请注意,我仍然使用Hibernate作为我的JPA持久层。

我通过将代码更改为

@Basic(optional = false)
@Column(name = "LastTouched", insertable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;

因此,在生成SQL插入时,时间戳列被忽略。我不确定这是不是最好的办法。欢迎反馈。

我意识到这有点晚了,但我已经成功地用

@Column(name="timestamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

这也适用于
当前日期
当前时间
。我在Oracle中使用JPA/Hibernate,所以YMMV。

我使用JPA2.0和MySQL 5.5.10可以很好地实现这一点,因为我只关心最后一次修改行的情况。MySQL将在第一次插入时创建一个时间戳,并且每次对行调用UPDATE时都会创建一个时间戳。(注意:如果我关心更新是否真的进行了更改,这将是一个问题)

本例中的“timestamp”列类似于“last toucted”列`

下面的代码使用单独的列“version”进行乐观锁定

private long version;
private Date timeStamp

@Version
public long getVersion() {
    return version;
}

public void setVersion(long version) {
    this.version = version;
}

// columnDefinition could simply be = "TIMESTAMP", as the other settings are the MySQL default
@Column(name="timeStamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
public Date getTimeStamp() {
    return timeStamp;
}

public void setTimeStamp(Date timeStamp) {
    this.timeStamp = timeStamp;
}
(注意:@Version不适用于MySQL的“DATETIME”列,其中实体类中的属性类型为“Date”。这是因为Date生成的值小于毫秒,但MySQL没有存储毫秒,所以当它比较数据库中的值和“attached”时实体,它认为它们有不同的版本号)

:


我不认为每个数据库都有自动更新时间戳(例如Postgres)。所以我决定在代码中的任何地方手动更新这个字段。这将适用于每个数据库:

thingy.setLastTouched(new Date());
HibernateUtil.save(thingy);
使用触发器是有原因的,但对于大多数项目来说,这不是其中之一。触发器可以让您更深入地了解特定的数据库实现

MySQL 5.6.28(Ubuntu 15.10,OpenJDK 64位1.8.066)似乎非常宽容,不需要任何其他东西

@Column(name="LastTouched")
MySQL 5.7.9(CentOS 6,OpenJDK 64位1.8.072)仅适用于

@Column(name="LastTouched", insertable=false, updatable=false)
不是:

我的其他系统信息(在两种环境中相同)

  • hibernate entitymanager 5.0.2
  • hibernate验证程序5.2.2
  • mysql连接器java 5.1.38
这对我有用。 这对我很有效:

@Column(name = "transactionCreatedDate", nullable = false, updatable = false, insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

添加
@CreationTimestamp
注释:

@CreationTimestamp
@Column(name="timestamp", nullable = false, updatable = false, insertable = false)
private Timestamp timestamp;

如果您使用
@DynamicInsert
标记实体,例如

@Entity
@DynamicInsert
@Table(name = "TABLE_NAME")
public class ClassName implements Serializable  {

Hibernate将生成不带
null
值的SQL。然后数据库将插入自己的默认值。这确实会影响性能,请参见[Dynamic Insert][1]。

这也适用于我:-

@Temporal(TemporalType.TIMESTAMP)   
@Column(name = "CREATE_DATE_TIME", nullable = false, updatable = false, insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
public Date getCreateDateTime() {
    return createDateTime;
}

public void setCreateDateTime(Date createDateTime) {
    this.createDateTime = createDateTime;
}

我发布这篇文章是为了让人们在使用MySQL和Java Spring Boot JPA时寻找答案,就像@immanuelRocha说的,Spring中的@Column中只有太多@CreationTimeStamp,在MySQL中,将默认值设置为“CURRENT_TIMESTAMP”

在Spring中,只添加以下行:

@列(name=“插入日期”)
@CreationTimestamp

私人时间戳插入日期如果您在Java 8和Hibernate 5或Spring Boot JPA中进行开发,则直接使用以下注释 在实体类中。Hibernate从VM获取当前时间戳,并将在数据库中插入日期和时间

public class YourEntity {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String name;
 
    @CreationTimestamp
    private LocalDateTime createdDateTime;
 
    @UpdateTimestamp
    private LocalDateTime updatedDateTime;
 
    …
}

实际上,再仔细考虑一下,我想我需要更新这个专栏,因为当我更改专栏时,我需要通过Java来更新它。除非有办法在数据库端进行列更新。根据,触发器是我应该在这里使用的。其他类型(如LocalDateTime)如何?使用此解决方案,我在类路径资源[org/springframework/boot/autoconfigure/orm/jpa/hibernatejbaconfiguration.class]中定义了名为“entityManagerFactory”的bean,创建时出现
错误:初始化方法调用失败;嵌套的异常是org.hibernate.AnnotationException:@Temporal应该只在java.util.Date或java.util.Calendar上设置
非常有用的信息,谢谢-我想很多人会因为升级到MySQL 5.7而被咬。x@James-谢谢,但我只是列出了我知道的差异。我不确定关键的区别是什么。它可能完全是另一回事。希望其他人能基于这个答案。是的,对不起,我应该补充一点,我在Ubuntu 14.04.1上从MySQL 5.6升级到5.7后遇到了这个错误(操作系统和JDK没有被修改)。所以我假设MySQL版本是这里的关键因素。@James-wow,这真的很有用。谢谢我已经更新了我的答案来反映这一点。这对我们很有效!我们将其与
insertable=false,updateable=false
ERROR 4371-[main]org.hibernate.tool.hbm2ddl.SchemaExport结合使用:您的SQL语法有错误;检查与您的MySQL服务器版本对应的手册,以了解在第1行
处使用的接近“
时间戳默认当前时间戳`not null,
完整内容”
longtext not null”的正确语法。我的列是:
@column(nullable=false,name=“created_at”,updateable=false,columnDefinition=“TIMESTAMP DEFAULT CURRENT_TIMESTAMP”)`和
private TIMESTAMP createdAt这是一个简短的a
@CreationTimestamp
@Column(name="timestamp", nullable = false, updatable = false, insertable = false)
private Timestamp timestamp;
@Entity
@DynamicInsert
@Table(name = "TABLE_NAME")
public class ClassName implements Serializable  {
@Temporal(TemporalType.TIMESTAMP)   
@Column(name = "CREATE_DATE_TIME", nullable = false, updatable = false, insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
public Date getCreateDateTime() {
    return createDateTime;
}

public void setCreateDateTime(Date createDateTime) {
    this.createDateTime = createDateTime;
}
public class YourEntity {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String name;
 
    @CreationTimestamp
    private LocalDateTime createdDateTime;
 
    @UpdateTimestamp
    private LocalDateTime updatedDateTime;
 
    …
}