在我的Mysql DB中,我有一些列需要使用hibernate以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;
答案 0 :(得分:4)
您可以在代码中手动执行此操作,特别是1列。基本上,我们的想法是在数据库中更新之前将日期更新到所需的日期。
为此,您需要在Hibernate的listener
中分配EventListenerRegistry
。以下类将在执行保存操作之前应用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);
}
}
以下类扩展了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);
}
以下是实体类。这个类将实现CreateUpdateTimestamp
,以便我们可以通过CreateUpdateTimestamp
中的CreateOrUpdateDateListener
参考来使用此类。
@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;
}
}