Есть ли проблема с объектами JPA, свойствами Oracle 10g и типами календаря?
Я испытываю следующее очень раздражающее поведение при использовании сущностей JPA в сочетании с Oracle 10g.
Предположим, что у вас есть следующая сущность.
@Entity
@Table(name = "T_Order")
public class TOrder implements Serializable {
private static final long serialVersionUID = 2235742302377173533L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "activationDate")
private Calendar activationDate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Calendar getActivationDate() {
return activationDate;
}
public void setActivationDate(Calendar activationDate) {
this.activationDate = activationDate;
}
}
Этот объект сопоставляется с Oracle 10g, поэтому в БД будет таблица T_ORDER с номером первичного ключа NUMBER "ID" и столбцом TIMESTAMP "activationDate".
Предположим, что я создаю экземпляр этого класса с датой активации "15. Sep 2008 00:00 AM". Мой часовой пояс - CEST, GMT + 02: 00. Когда я сохраняю этот объект и выбираю данные из таблицы T_ORDER с помощью sqlplus, я обнаруживаю, что в таблице фактически "14. Sep 2008 22:00" сохраняется, что пока нормально, потому что часовой пояс oracle db - GMT.
Но теперь раздражающая часть. Когда я прочитал этот объект обратно в свою программу JAVA, я узнаю, что часовой пояс оракула игнорируется, и я получаю "14. сент. 2008 22:00 CEST", что совершенно неверно.
В принципе, при записи в БД будет использоваться информация о часовом поясе, при чтении она будет проигнорирована.
Есть ли какое-либо решение для этого? Самое простое решение, по-моему, было бы установить часовой пояс oracle dbs на GMT + 02, но, к сожалению, я не могу этого сделать, потому что есть другие приложения, использующие один и тот же сервер.
Мы используем следующую технологию
MyEclipse 6.5
JPA с Hibernate 3.2
Драйвер JDBC Oracle 10g
Ответы
Ответ 1
Вы не должны использовать Календарь для доступа к датам из базы данных по этой точной причине. Вы должны использовать java.util.Date
так:
@Temporal(TemporalType.TIMESTAMP)
@Column(name="activationDate")
public Date getActivationDate() {
return this.activationDate;
}
java.util.Date
указывает на момент времени, независимо от любых временных зон. Календарь можно использовать для форматирования даты определенного часового пояса или локали.
Ответ 2
У меня уже была своя доля проблем с JPA и метками времени. Я читал в oracle forums и, пожалуйста, проверьте следующее:
- Поле в базе данных должно быть TIMESTAMP_TZ, а не только TIMESTAMP
- Попробуйте добавить аннотацию @Temporal (value = TemporalType.TIMESTAMP)
- Если вам действительно не нужен часовой пояс, введите поле даты или времени.