我在Oracle中有一个表,带有带时区(TIMESTAMPTZ)列类型的时间戳 . 我还在此表上有一个触发器,用于将传入时间戳从本地时区(EST)转换为GMT . 当我使用SqlPlus / SQL Developer将数据插入表时,触发器运行良好并正确转换时区 . 但是当我尝试从Java应用程序插入数据(使用JPA / EclipseLink)时,时间四舍五入到最接近的整秒(丢失小数部分) . 如果禁用触发器,则会正确插入时间,但在本地时区除外 .
我知道我可以通过在我的Java应用程序中执行GMT转换来解决这个问题 . 但是,有多种方法可以将数据插入到此表中,并且需要更改许多应用程序,一些Java和一些SQL . 因此,我们在触发器中执行转换更方便 . 以前有人遇到过这个吗?任何帮助修复扳机将不胜感激 .
样本记录,
触发器从Java禁用或从SQL开发人员插入
Id TS_COL TS_TZ_COL
101 21-FEB-16 13.10.10.223000000 21-FEB-16 13.10.10.223000000 AMERICA/NEW_YORK
插入时启用触发器
Id TS_COL TS_TZ_COL
103 21-FEB-16 14.22.02.654000000 21-FEB-16 19.22.02.000000000 GMT
这是一个用来说明问题的小例子 . 我正在使用Oracle 12.1.0并在Redhat Enterprise和Windows 10上运行的两个实例上都尝试过这个 . 任何帮助都会很有用 .
表和触发器定义
CREATE TABLE TZ_TEST ( myid NUMBER (4,0) not null primary key, TS_COL TIMESTAMP (6), TS_TZ_COL TIMESTAMP (6) WITH TIME ZONE)
CREATE OR REPLACE
TRIGGER TZ_TEST_TRIGGER
BEFORE INSERT OR UPDATE ON TZ_TEST
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
BEGIN
IF (:NEW.TS_TZ_COL is not null)
THEN
:NEW.TS_TZ_COL := (from_tz(cast(:NEW.TS_TZ_COL as timestamp), 'America/New_York') at time zone 'GMT');
END IF;
END;
JPA实体
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="TZ_TEST")
public class TzTest implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="myid")
private long id;
@Column(name="TS_COL")
private Timestamp tsCol;
@Column(name="TS_TZ_COL")
private Timestamp tsTzCol;
public TzTest() {
}
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public Timestamp getTsCol() {
return this.tsCol;
}
public void setTsCol(Timestamp tsCol) {
this.tsCol = tsCol;
}
public Timestamp getTsTzCol() {
return this.tsTzCol;
}
public void setTsTzCol(Timestamp tsTzCol) {
this.tsTzCol = tsTzCol;
}
}
测试插入记录的代码
@Test
public void test() throws ParseException {
Timestamp ts1 = new Timestamp(System.currentTimeMillis());
TzTest tzTest1 = new TzTest();
tzTest1.setId(103);
tzTest1.setTsCol(ts1);
tzTest1.setTsTzCol(ts1);
em.getTransaction().begin();
em.persist(tzTest1);
em.getTransaction().commit();
}