我的行为非常奇怪。我正在创建一个具有LocalDate字段的实体,并且在数据库中插入但在某些情况下会更改数据库中的值。这是使用调试器记录的SQL:
[EL Fine]: sql: 2016-11-19 21:31:57.979
--ClientSession(1809129176)--Connection(1261635736)
--Thread(Thread[main,5,main])
--INSERT INTO vcc_task (creator_user, execution_end_time, execution_start_time, last_edit_time, last_edit_user, server_name, state, thread_name, version, task_type, cc_service_id, vcc, start_time, end_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
bind => [user@vccModel1, null, null, 2016-11-20 00:31:46.016, user@vccModel1, , 0, , 1, 0, c1, vccModel1, 2017-05-06, 2017-05-07]
请注意“ 2017-05-06,2017-05-07 ”。 但是如果我查询postgreSQL:
SELECT * FROM vcc_task
我写的其他测试没有出错。他们在数据库中保存了正确的日期。所以,我很困惑。
如果我使用我用来存储taskEntity的相同EntityManager查询数据库,我会得到一个具有正确日期的实体。但是如果我使用不同的EntityManager进行查询,我会从数据库中获取日期,即正确日期前一天。这是有道理的,因为EM从其缓存返回。但是我仍然不明白谁正在改变日期,为什么有时会这样做,有时它不会。
例如,以下测试传递使用两个LocalDate构造函数:
// private final LocalDate startTime = LocalDate.parse("2017-05-06");
// private final LocalDate endTime = LocalDate.parse("2017-06-06");
private final LocalDate startTime = Instant.parse("2017-05-06T00:00:00Z").atZone(ZoneOffset.UTC).toLocalDate();
private final LocalDate endTime = Instant.parse("2017-06-06T00:00:00Z").atZone(ZoneOffset.UTC).toLocalDate();
em = MyEntityManager.getEntityManager();
final TaskDT tdt = new TaskDT(taskType, ccService, startTime, endTime, userName);
t1 = new TaskEntity(userName, vcc, tdt);
PersistLogic.persist(em, t1);
em.close();
em = MyEntityManager.getEntityManager();
final TaskEntity t2 = em.find(TaskEntity.class, tid);
em.close();
Assert.assertNotNull(t2, "Task does exist");
Assert.assertEquals(t2.getVersion(), 1, "Resource Version");
Assert.assertEquals(t2.getLastEditUser(), userName, "Resource Version");
Assert.assertEquals(t2.getId().getVcc(), vcc, "getVcc");
Assert.assertEquals(t2.getId().getTaskType(), taskType, "getTaskType");
Assert.assertEquals(t2.getId().getCcService(), ccService, "getCcService");
Assert.assertEquals(t2.getId().getStartTime(), startTime, "getStartTime");
Assert.assertEquals(t2.getId().getEndTime(), endTime, "getEndTime");
...
当我在代码中创建实体时,问题就出现了:
// create the task
final LocalDate taskFromD = toLocalDate(tmpFrom);
final LocalDate taskToD = toLocalDate(tmpTo);
final TaskDT taskDT = new TaskDT(taskType, ccServiceName, taskFromD, taskToD, userName);
final TaskEntity newTask = new TaskEntity(userName, vccName, taskDT);
PersistLogic.persist(em, newTask);
它看起来一样,但表现不同。
更新
这是我将Instant转换为LocalDate以传递给实体的方式:
private static LocalDate toLocalDate(Instant i) {
return i.atZone(ZoneOffset.UTC).toLocalDate();
}
这是我将LocalDate转换为Date并返回的方式:
import java.sql.Date;
import java.time.LocalDate;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate locDate) {
return (locDate == null ? null : Date.valueOf(locDate));
}
@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}
任何帮助将不胜感激。 感谢
答案 0 :(得分:0)
我猜问题是在convertToDatabaseColumn()方法中调用Date.valueOf(locDate),这里生成的瞬间是系统默认时区中此日期的午夜>。 / p>