【问题标题】:I used LocalDate my whole project, now it turns out i need LocalDateTime for a functionality, what to do?我在整个项目中使用了 LocalDate,现在我需要 LocalDateTime 来实现功能,该怎么办?
【发布时间】:2020-09-11 10:26:13
【问题描述】:

我正在创建一个即将完成的博客。 LocalDate 一切正常,直到管理员创建帖子时,“创建日期”和“修改日期”被添加到保存在 MySQL 数据库中的帖子中。每次用户更新帖子时,“修改”日期都会更改。

我想添加的最后一个功能是显示管理员按降序发布的最后 3 个帖子。现在问题来了:如果管理员在同一天一个接一个地添加 3 个帖子,则 LocalDate 无法对它们进行排序,因为它无法区分它们,因为它们都有相同的标准日期,并且时间不存在。

我尝试修改我的 JPA 查询以及每个实体字段和方法以使用 LocalDateTime 而不是 LocalDate,但后来发生了这种情况:

@Repository
public interface PostRepository extends CrudRepository<Post, Long> {
    List<Post> findAllByCreatedAtBetween(LocalDateTime start, LocalDateTime end);
    List<Post> findAllByOrderByCreatedAtDesc();
}
java.lang.IllegalArgumentException: Parameter value [2020-09-01T12:27:19.341] did not match expected type [java.time.LocalDate (n/a)]

我在某处读到“中间”不适用于 LocalDateTime,现在我的整个项目都坏了。

我很困惑,也很恼火,我这么晚才发现 LocalDate 在灵活性方面是错误的选择。请帮助我了解我现在有哪些选项可以使该功能正常工作。 任何帮助将不胜感激!

Post 类:

@Entity
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Long id;
   
    private LocalDateTime createdAt;
   
    private LocalDateTime modifiedAt;

    @NotBlank(message = "Post Title is required")
    private String title;

    @Basic(fetch = FetchType.LAZY)
    private String image;

    @Column(length = 65535,columnDefinition="Text")
    @NotBlank(message = "Post Content is required")
    private String content;

    @OneToMany(cascade = CascadeType.ALL)
    private List<Comment> comments = new ArrayList<>();

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "POST_TAG", joinColumns = {@JoinColumn(name = "post_id")},
            inverseJoinColumns = {@JoinColumn(name = "tag_id")})
    private Set<Tag> tags = new HashSet<>();

对于遇到相同问题的任何人来说,这次会更容易,而不是进行破坏整个代码的修改以仅按 ID 对实体进行排序。但是下次从一开始就选择一个为您提供更多灵活性的类(如 LocalDateTime),因为您永远不知道接下来需要实现什么。

【问题讨论】:

  • 方法findAllByCreatedAtBetween的代码是什么?
  • 为什么不能按记录 ID 对帖子进行排序,因为每个新帖子都会增加记录 ID。
  • @deHaar 这只是一个 jpa 查询,我使用 between 字和 2 个参数。就是这样,没有其他代码。
  • 对应的数据库表列的类型是什么?是 DATE 还是 DATETIME 还是其他什么?可能很重要......
  • 你能显示Postclass的代码吗?我猜里面有一个LocalDate。否则,您必须找出异常消息中的 LocalDate 来自哪里。

标签: java spring spring-boot hibernate jpa


【解决方案1】:
  1. 正如评论中所建议的,您可以按记录 ID 对帖子进行排序,记住每个新帖子都会增加记录 ID。

  2. 请注意,您使用已弃用的hibernate dialect。正如对该方言的评论所述:

改用“hibernate.dialect.storage_engine=innodb”环境变量或JVM系统属性。

使用这种方言还会导致日期/时间数据类型的映射问题。参见例如this

【讨论】:

    【解决方案2】:

    如果您使用 Intellij 作为 ide,您可以修改方法签名,然后在更改签名时提供默认值。

    您也可以使用快捷键替换所有出现的any语句并全部替换。

    【讨论】:

    • 你能给我举个例子吗?
    • ctrl + shift + r ==> 将用您打算放入所有文件中的内容替换语句的出现。 & ctrl + F6,将允许您更改方法签名
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 2016-04-06
    • 2013-11-14
    • 1970-01-01
    相关资源
    最近更新 更多