java - Apache Cassandra 的 Spring Data 将 java.time.LocalDateTime 转换为 UTC

标签 java spring cassandra timezone spring-data-cassandra

我试图在我的 Cassandra 数据库中保留一个 java.time.LocalDateTime 对象并使其与时区无关。我正在使用 Spring Data Cassandra 来执行此操作。

问题是在某个地方,有些东西正在处理这些 LocalDateTime 对象,就好像它们在我的服务器的时区中一样,并在将它们存储在数据库中时将它们偏移到 UTC 时间。

这是错误还是功能?我可以通过某种方式解决它吗?

配置:

@Configuration
@EnableCassandraRepositories(
    basePackages = "my.base.package")
public class CassandraConfig extends AbstractCassandraConfiguration{

    @Override
    protected String getKeyspaceName() {
        return "keyspacename";
    }

    @Bean
    public CassandraClusterFactoryBean cluster() {
        CassandraClusterFactoryBean cluster =
            new CassandraClusterFactoryBean();
        cluster.setContactPoints("127.0.0.1");
        cluster.setPort(9142);
        return cluster;
    }

    @Bean
    public CassandraMappingContext cassandraMapping()
        throws ClassNotFoundException {
        return new BasicCassandraMappingContext();
    }
}

我希望保留的预订记录:

@Table("booking")
public class BookingRecord {
    @PrimaryKeyColumn(
        ordinal = 0,
        type = PrimaryKeyType.PARTITIONED
    )
    private UUID bookingId = null;

    @PrimaryKeyColumn(
        ordinal = 1,
        type = PrimaryKeyType.CLUSTERED,
        ordering = Ordering.ASCENDING
    )
    private LocalDateTime startTime = null;
    ...
}

简单的存储库界面:

@Repository
public interface BookingRepository extends CassandraRepository<BookingRecord> { }

保存通话:

...

@Autowired
BookingRepository bookingRepository;

...

public void saveBookingRecord(BookingRecord bookingRecord) {
    bookingRepository.save(bookingRecord);
}

这是用于填充 BookingRecord 开始时间的字符串:

"startTime": "2017-06-10T10:00:00Z"

这是持久化时间戳后 cqlsh 的输出:

cqlsh:keyspacename> select * from booking ;

 bookingid                            | starttime               
--------------------------------------+--------------------------------
 8b640c30-4c94-11e7-898b-6dab708ec5b4 | 2017-06-10 15:00:00.000000+0000 

最佳答案

Cassandra 将日期(时间戳)存储为 milliseconds since epoch without a specific timezone information .时区数据在 Cassandra 之上的层中处理。

LocalDate/LocalDateTime 表示相对于本地时间的时间点。在保存日期/时间之前,需要使用时区对其进行增强以计算可以保存的通用表示。

Spring Data 使用您的系统默认时区 ( Date.from(source.atZone(systemDefault()).toInstant()) )。

如果您需要时区精度并希望省略任何隐式时区转换,请直接使用 java.util.Date,它对应于 Cassandra 的(准确地说是 Datastax 驱动程序)存储格式表示。

关于java - Apache Cassandra 的 Spring Data 将 java.time.LocalDateTime 转换为 UTC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44448899/

相关文章:

java - 空字符串末尾有 "\u0000"

java - 如何在 super 抽象类中使用@Bean?

mysql - (Spring) 使用数据库表执行授权

java - 使用 Spark 将数据保存到 Cassandra

java - 需要将控制从 Action 类发送到 JSP

java - JPQL IS NOT NULL 返回带有 NULL 的对象

java - 使用 Redis 的 Spring 启动 session 中出现错误 - 没有 [...SessionRepository] ​​类型的合格 bean

java - Spring 4 WebSocket 远程代理配置

c# - 如何使用 C# 驱动程序更新 cassandra 中的时间戳字段?

java - 使用 DSE 的 Java API 映射 Cassandra 物化 View