7

LocalDateTimejava.time中的类是基于值的类。如果我有一个使用这样的对象作为字段的实体,我会遇到以下“问题”:不应序列化基于值的类。但是,JPA 实体必须实现接口 Serializable。这个悖论的解决方案是什么?不应该有人使用 LocalDateTime 作为 JPA 实体的字段吗?改用日期?这将是不令人满意的。

这个问题是声纳规则squid:S3437,因此项目中有很多错误,因为我们从 Date 更改为 LocalDateTime ...

由于基于值的类使用导致不合规的解决方案:

@Entity
public class MyEntity implements Serializable{
    @Column
    private String id; // This is fine
    @Column
    private LocalDateTime updated; // This is not ok, as LocalDateTime is a value based class
    @Column
    private Date created; // This however is fine..
}
4

2 回答 2

2

我的回答可能看起来很直接且毫无价值,但更多的是为了整理和总结。

首先,这个问题没有“金子弹”解决方案。有些东西肯定需要改变,我看到 3 个选项或 3 个替代方案:

  1. 删除Serializable接口。Serializable放在所有实体上并不是一个“好习惯” 。仅当您要将它的实例用作分离对象时才需要它:JPA 实体何时以及为什么应该实现 Serializable 接口?.

  2. 使用 Timestamp 类型而不是 LocalDateTime。在我看来,它是等价的:

https://github.com/javaee/jpa-spec/issues/63

Instant、LocalDateTime、OffsetDateTime 和 ZonedDateTime 默认映射为时间戳值。您可以使用@TeMPORaL 标记其中一种类型的属性,以指定不同的策略来持久化该属性。

  1. 如果两个第一个选项都不适合您,那么(我很确定,您知道该怎么做) - 禁止显示此警告@SuppressWarnings("squid:S3437")
于 2017-12-18T14:20:20.703 回答
1

我不太明白你的数据库从 jpa 接受了什么。当我处理 Postgres 时,我使用自定义转换器:

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.sql.Timestamp;
import java.time.LocalDateTime;

@Converter(autoApply = true)
public class LocalDateTimePersistenceConverter implements AttributeConverter<LocalDateTime, Timestamp> {

    @Override
    public Timestamp convertToDatabaseColumn(LocalDateTime locDateTime) {
        return (locDateTime == null ? null : Timestamp.valueOf(locDateTime));
    }

    @Override
    public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
        return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime());
    }
}

我这样使用它:

@Column(name = "create_date")
@Convert(converter = LocalDateTimePersistenceConverter.class)
private LocalDateTime createDate;

你看,这里我将 LocalDateTime 转换为 Timestamp(被 postgres 接受)并返回。

于 2017-12-18T11:50:49.970 回答