如何在休眠中仅存储 UTC 中的特定时间戳列
How to store only specific timestamp columns in UTC in hibernate
在我的 Mysql 数据库中,我有一些列需要使用休眠以 UTC 格式存储。我不能强制我的 JVM 以 UTC 格式存储所有时间戳列,因为我有针对不同时区的其他列。我找到了两个解决方案
1) To configure hostname as jdbc:mysql://hostname/databaseName?useTimezone=true&serverTimezone=UTC
2) private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
但这两种解决方案都是针对所有列强制使用 UTC 时区,而我的要求是针对特定列。
@CreatedDate
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false,updatable = false, name="created_at")
private Date createdAt;
您可以在代码中手动执行此操作,特别是 1 列。基本上,想法是在更新数据库之前将日期更新为所需日期。
为此,您需要在 Hibernate 的 EventListenerRegistry
中分配一个 listener
。以下 class 将在执行保存操作之前应用 CreateOrUpdateDateListener
侦听器(由您创建)。
@Component
public class HibernateEventWiring {
@Autowired
@Qualifier(value = "your_sessionFactory") //Your session factory
private LocalSessionFactoryBean sessionFactory;
@Autowired
private CreateOrUpdateDateListener listener;
@PostConstruct
public void registerListeners() {
EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory.getObject()).getServiceRegistry().getService(
EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.SAVE_UPDATE).appendListener(listener);
}
}
以下 class 扩展了 DefaultSaveOrUpdateEventListener 并添加了将时间戳更新为所需内容的自定义代码。而且,我们在 EventListenerRegistry
中将它的对象用作侦听器
@Component
public class CreateOrUpdateDateListener extends DefaultSaveOrUpdateEventListener {
@Override
public void onSaveOrUpdate(SaveOrUpdateEvent event) {
if (event.getObject() instanceof CreateUpdateTimestamp) {
CreateUpdateTimestamp record = (CreateUpdateTimestamp) event.getObject();
record.setUpdatedTimestamp(LocalDateTime.now(Clock.systemUTC()));
}
super.onSaveOrUpdate(event);
}
}
public interface CreateUpdateTimestamp {
public void setCreatedTimestamp(LocalDateTime date);
public void setUpdatedTimestamp(LocalDateTime date);
}
以下是实体class。 class 将实现 CreateUpdateTimestamp
,这样我们就可以通过 CreateOrUpdateDateListener
.
中的 CreateUpdateTimestamp
引用来使用 class
@Entity
@Table(name = "transactions")
public class Transaction implements CreateUpdateTimestamp{
private LocalDateTime updatedTimestamp;
@Column(name = "updated_timestamp", insertable = true, updatable = true)
public LocalDateTime getUpdatedTimestamp() {
return updatedTimestamp;
}
public void setUpdatedTimestamp(LocalDateTime updatedTimestamp) {
this.updatedTimestamp = updatedTimestamp;
}
}
在我的 Mysql 数据库中,我有一些列需要使用休眠以 UTC 格式存储。我不能强制我的 JVM 以 UTC 格式存储所有时间戳列,因为我有针对不同时区的其他列。我找到了两个解决方案
1) To configure hostname as jdbc:mysql://hostname/databaseName?useTimezone=true&serverTimezone=UTC
2) private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
但这两种解决方案都是针对所有列强制使用 UTC 时区,而我的要求是针对特定列。
@CreatedDate
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false,updatable = false, name="created_at")
private Date createdAt;
您可以在代码中手动执行此操作,特别是 1 列。基本上,想法是在更新数据库之前将日期更新为所需日期。
为此,您需要在 Hibernate 的 EventListenerRegistry
中分配一个 listener
。以下 class 将在执行保存操作之前应用 CreateOrUpdateDateListener
侦听器(由您创建)。
@Component
public class HibernateEventWiring {
@Autowired
@Qualifier(value = "your_sessionFactory") //Your session factory
private LocalSessionFactoryBean sessionFactory;
@Autowired
private CreateOrUpdateDateListener listener;
@PostConstruct
public void registerListeners() {
EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory.getObject()).getServiceRegistry().getService(
EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.SAVE_UPDATE).appendListener(listener);
}
}
以下 class 扩展了 DefaultSaveOrUpdateEventListener 并添加了将时间戳更新为所需内容的自定义代码。而且,我们在 EventListenerRegistry
@Component
public class CreateOrUpdateDateListener extends DefaultSaveOrUpdateEventListener {
@Override
public void onSaveOrUpdate(SaveOrUpdateEvent event) {
if (event.getObject() instanceof CreateUpdateTimestamp) {
CreateUpdateTimestamp record = (CreateUpdateTimestamp) event.getObject();
record.setUpdatedTimestamp(LocalDateTime.now(Clock.systemUTC()));
}
super.onSaveOrUpdate(event);
}
}
public interface CreateUpdateTimestamp {
public void setCreatedTimestamp(LocalDateTime date);
public void setUpdatedTimestamp(LocalDateTime date);
}
以下是实体class。 class 将实现 CreateUpdateTimestamp
,这样我们就可以通过 CreateOrUpdateDateListener
.
CreateUpdateTimestamp
引用来使用 class
@Entity
@Table(name = "transactions")
public class Transaction implements CreateUpdateTimestamp{
private LocalDateTime updatedTimestamp;
@Column(name = "updated_timestamp", insertable = true, updatable = true)
public LocalDateTime getUpdatedTimestamp() {
return updatedTimestamp;
}
public void setUpdatedTimestamp(LocalDateTime updatedTimestamp) {
this.updatedTimestamp = updatedTimestamp;
}
}