2017-02-19 19 views
13

Tôi có hai loại cổ phiếu nàysao chép dấu thời gian để DATETIME trên MySQL với Hibernate

class Source { 
    // mapped to TIMESTAMP 
    @Version 
    @Column(columnDefinition="TIMESTAMP(3) DEFAULT '2016-01-01'") 
    Instant myInstant; 
} 

class Destination { 
    // mapped to DATETIME 
    @Basic(optional=true) 
    Instant myInstant; 
} 

Khi sử dụng Hibernate, tôi gán

destination.myInstant = source.myInstant; 

và sau đó giá trị được lưu trữ là nhỏ hơn bằng cách một giờ so với bản gốc - cả hai theo dòng lệnh của MySQL client và trong Java. Múi giờ hiện tại của tôi là UTC + 1, vì vậy lý do rõ ràng là chuyển đổi múi giờ.

Có một vài nơi mà điều này có thể được khắc phục, nhưng tôi đang tìm cách thực hành tốt nhất. Máy chủ nên làm việc trên toàn thế giới, vì vậy nó sẽ tiếp tục sử dụng UTC nội bộ, phải không?

Tôi có nên thay đổi loại cột thành TIMESTAMP không? Sau đó, tại sao Instant theo bản đồ mặc định là DATETIME?


Theo this article, Instantlàm đồ-TIMESTAMP, nhưng trong trường hợp của tôi nó không. Tại sao?

+0

Vui lòng cung cấp 'SHOW CREATE TABLE' và SQL được tạo từ Hibernate. –

+0

@RickJames Không có gì thú vị ở đó: 'SHOW CREATE TABLE' hiển thị các kiểu như' dấu thời gian (3) NOT NULL DEFAULT '2016-01-01 01: 00: 00.000' và 'datetime'. Các câu lệnh chỉ đơn giản là chọn và cập nhật, không có logic đằng sau. Các giá trị không được ghi lại. Dù sao tôi cũng đã đăng nhật ký, nhưng tôi phải thay thế tên thật và tên trường bằng những cái được sử dụng trong câu hỏi của tôi và điều đó không đáng giá vì không có gì ở đó cả. – maaartinus

+0

'HIỂN THỊ VARIABLES LIKE '% zone%';' –

Trả lời

1

Trong MySQL 5 & ở trên, giá trị TIMESTAMP được chuyển đổi từ múi giờ hiện tại sang UTC để lưu trữ và chuyển đổi từ UTC sang múi giờ hiện tại để truy xuất. Điều này chỉ xảy ra cho loại dữ liệu TIMESTAMP nhưng không chỉ cho DATETIME. Đây là lý do bạn thấy sự khác biệt khi chỉ định TIMESTAMP đến DATETIME. Vì vậy, có cả hai cột cùng loại sẽ hoạt động. Hibernate theo mặc định bản đồ InstantType để cơ sở dữ liệu loại TIMESTAMP. Mặc dù bạn có thể sử dụng nó cho cả TIMESTAMP và DATETIME trong MYSQL, chúng được xử lý khác nhau.

5

Nếu bạn muốn làm việc với múi giờ và Java 8, tôi khuyên bạn nên sử dụng ZonedDateTime hoặc OffsetTimeZone (tùy chọn sau được ưu tiên khi làm việc với Hibernate). Đối với các phiên bản cũ hơn, hãy sử dụng Lịch.

  • Khi bạn dụ nó sẽ đi theo mặc định với múi giờ của máy tính.
  • Kiểm tra xem cơ sở dữ liệu có dấu thời gian có hoặc không có múi giờ.
  • Mặc định bạn đặt cũng không có múi giờ và nếu múi giờ là "có múi giờ", nó sẽ tự động thêm bù đắp của cơ sở dữ liệu.

Tôi hy vọng một số tính năng này hoạt động. Đây là cách tôi đã làm trong một trong các dự án của tôi.

@Column(name = "registration_time") 
private OffsetDateTime registrationTime; 
[...] 
subscriber.setRegistrationTime(OffsetDateTime.now()); 
+0

Tôi không hoàn toàn hài lòng với câu trả lời của bạn, nhưng đây không phải là lỗi của bạn. Tôi sẽ phải điều tra thêm những gì đang diễn ra (xem câu trả lời của tôi cho Rick James). – maaartinus

Các vấn đề liên quan