如何在 Oracle 中使用 JPA 存储日期和时间?

Posted

技术标签:

【中文标题】如何在 Oracle 中使用 JPA 存储日期和时间?【英文标题】:how to store date AND time with JPA in Oracle? 【发布时间】:2012-06-04 21:35:04 【问题描述】:

我正在使用 WebSphere 7 (Java EE 5) 和 OpenJPA 1.2.1。

我有一个带有“modifiedTimestamp”属性的 JPA 对象,如下所示:

@Entity
public class Widget 
  /* ... */
  private java.sql.Date modifiedTimestamp;
  /* ... */

Oracle 数据库中相关字段的类型为DATE

我是这样设置日期的......

myWidget.setModifiedTimestamp(new java.sql.Data(System.currentTimeMillis());

...它被存储了,但是当我读回它时,一天中的时间还没有被存储,它允许返回为 24:00。

这是 JPA 的事情,还是 Oracle 的事情?任何建议都非常感谢!

谢谢

【问题讨论】:

好问题——我正在使用 WebSphere 7 (Java EE 5) 和 OpenJPA 1.2.1。 java.sql.Date 根据其 javadocs 仅存储日期。也许你想要 java.util.Date? 查看***.com/questions/2188768/… 了解休眠,我想你可以试试 当我将代码更改为private java.util.Date modifiedTimestamp 时,自动映射似乎中断了,我收到此错误java.lang.NoSuchMethodError: com/myapp/domain/Widget.getModifiedTimestamp()Ljava/sql/Data 你必须重新编译 Widget.java ;有疑问时清理它。 【参考方案1】:

注释您的字段并更改类型应该会有所帮助:

@Temporal(TemporalType.TIMESTAMP)
private java.util.Date modifiedTimestamp;

【讨论】:

注意:为了使其正常工作,我还将 Oracle 字段更改为 TIMESTAMP 而不是 DATE。 在我的例子中(Oracle 11g),Oracle 中的 DATE 数据类型也可以工作。 不要这么认为 Calendar 已经很老了,我从未见过它与 JPA 一起使用。 “新”日期时间 API 在 java.time 中,但我从未将它与 JPA 一起使用,因为我近年来没有使用 java。实际上,我倾向于尽可能多地使用 JodaTime,因为它有一个更健全的 API,java.time 是基于它的。【参考方案2】:

使用@Temporal(TemporalType.TIMESTAMP) (Javadocs)。合并with java.util.Date。

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "DATE_FIELD")
private java.util.Date modifiedTimestamp;

【讨论】:

感谢@AnthonyAccioly,我想将其标记为正确,Eelke 在几秒钟内击败了您。 :) 感谢@AnthonyAccioly,我的案例中缺少 Column 注释,并根据您的建议进行了修复。【参考方案3】:

我看到这个问题之前有人问过,所以我建议阅读 this 文章。引入 java 8 日期类型后有一些变化。我知道这不是这个问题的答案,而且我遇到的问题不同,但我发布这个是因为我在答案中看到的 @Temporal() 注释破坏了我的 CI 管道:

这行得通:

@NotNull
@Column(nullable = false, columnDefinition = "TIME") // this bit is different
@JsonFormat(pattern="HH:mm")
private LocalTime startTime;

这不是:

@NotNull
@Column(nullable = false)
@Temporal(TemporalType.TIME)
@JsonFormat(pattern="HH:mm")
private LocalTime startTime;

【讨论】:

【参考方案4】:

如果您将类型更改为java.sql.Timestamp,那么它也应该可以工作,而无需添加@Temporal 注释。

private java.sql.Timestamp modifiedTimestamp; 

当然在 Oracle 中将字段更改为 TIMESTAMP。

【讨论】:

【参考方案5】:

这就是我在 Java、mysql db 和 OpenJPA2 中处理日期时间字段的方式。我希望字段是 java.util.Calendar 类型,dbfield datetime 和 dbvalue 作为 UTC 值。 Mysql 对时区一无所知,因此使用自定义转换器可以设置和读取“yyyy-MM-dd HH:mm:ss”字符串。仍然是实体 bean 中的有效日期时间 sql 列和 java.util.Calendar。

@Entity @Table(name="user") @Access(AccessType.FIELD)
public class User 
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;    // primary key (autogen surrogate)

    private String name;

    @Column(name="updated_utc") // use custom serializer so that UTC-stringified
    @Temporal(TemporalType.TIMESTAMP) // db datetime is properly set to calendar instance
    @Factory("JPAUtil.db2calendar") @Externalizer("JPAUtil.calendar2db")
    private Calendar updated;

    public long getId()  return id; 
    public void setId(long id)  this.id = id; 

    public String getName()  return name; 
    public void setName(String name)  this.name=name; 

    public Calendar getUpdated()  return updated; 
    public void setUpdated(Calendar cal)  updated=cal; 



- - - 

public class JPAUtil 
    public static final TimeZone TIMEZONE_UTC = TimeZone.getTimeZone("UTC");

    public static String calendar2db(Calendar val, StoreContext ctx) 
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        df.setTimeZone(TIMEZONE_UTC);
        return df.format(cal.getTime()); // return date as UTC string value
    

    public static Calendar db2calendar(String val, StoreContext ctx) 
        try 
            // returned calendar is using a default timezone, val was set as utc string
            return DateUtil.parseDateTimeFromUTC(val);
         catch (Exception ex)  
            return null;
        
    



- - - 

CREATE TABLE user (
  id bigint NOT NULL auto_increment,
  name varchar(64) NOT NULL default '',
  updated_utc datetime NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY USERNAME (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;

ps:DateUtil 是我的随机工具类,用于提供一些基本的转换。

【讨论】:

以上是关于如何在 Oracle 中使用 JPA 存储日期和时间?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JPA 将 Java 日期存储到 Mysql 日期时间

如何正确地转换成 java.util.Date 通过 JPA 的 Oracle 日期字段

使用 Spring Data Jpa 在 Oracle 中调用存储过程时参数的数量或类型错误

在 Oracle 时间戳列中以 UTC 保存日期

oracle过程中如何循环指定日期到当前日期,并且我要拿到这个日期

oracle中如何设置年月日?