Как хранить только определенные столбцы меток времени в 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;
    }
}
Другие вопросы по тегам