Как хранить только определенные столбцы меток времени в UTC в спящем режиме
В моей Mysql DB у меня есть несколько столбцов, которые нужно хранить в UTC, используя hibernate. Я не могу заставить мою 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 ответ
Вы можете сделать это вручную в своем коде, особенно для 1 столбца. По сути, идея состоит в том, чтобы обновить дату до желаемой даты непосредственно перед обновлением в БД.
Для этого вам нужно будет назначить 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;
}
}