I used LocalDate my whole project, now it turns out i need LocalDateTime for a functionality, what to do?

huangapple go评论76阅读模式
英文:

I used LocalDate my whole project, now it turns out i need LocalDateTime for a functionality, what to do?

问题

我正在创建一个几乎完成的博客。在使用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)]

我在某个地方读到“between”在LocalDateTime上不起作用,现在我的整个项目都出问题了。

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

Post类:

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

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

    @NotBlank(message = "帖子标题不能为空")
    private String title;

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

    @Column(length = 65535, columnDefinition = "Text")
    @NotBlank(message = "帖子内容不能为空")
    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),因为您永远不知道您需要在将来实现什么。

英文:

I was creating a blog which is almost finished. Everything worked ok with LocalDate until one point, when the admin creates a post a "creation date" and a "modified date" are added to that post which is saved in the MySQL database. Every time the user updates the post the "modified" date is changed.

One of the last functionalities I wanted to add was displaying the last 3 posts that where posted by the admin in a descending order. Now here is the problem: If the admin adds 3 post in the same day one after the other, then LocalDate is not able to sort them since it cannot distinguish between them since all have the same standard date, and the time is absent.

I tried modifying my JPA queries and every entity field and method to use LocalDateTime instead of LocalDate, but then this happens:

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

I read somewhere that 'between' does not work with LocalDateTime, now my whole project is broken.

I am confused and really annoyed I found out so late that LocalDate was the wrong choice in term of flexibility. Please help me understand what options do I have now in order to make that functionality work.
Any help would be greatly appreciated!

The Post class:

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

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

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

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

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

    @OneToMany(cascade = CascadeType.ALL)
    private List&lt;Comment&gt; comments = new ArrayList&lt;&gt;();

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = &quot;POST_TAG&quot;, joinColumns = {@JoinColumn(name = &quot;post_id&quot;)},
            inverseJoinColumns = {@JoinColumn(name = &quot;tag_id&quot;)})
    private Set&lt;Tag&gt; tags = new HashSet&lt;&gt;();

For anyone struggling with the same issue, it is easier this time, instead of doing modifications that break the whole code to just sort the entities by ID. But next time pick a class that offers you more flexibility (like LocalDateTime) from the start since you never know what you need to implement down the line.

答案1

得分: 1

  1. 正如评论中所建议的,您可以按记录ID对帖子进行排序,要记住它会在每篇新帖子时递增。

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

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

使用此方言还可能导致日期/时间数据类型的映射问题。例如,请参阅此链接

英文:
  1. As was suggested in the comment you can sort your posts by record ID taken in mind that it's incremented for each new post.

  2. Please note that you use deprecated hibernate dialect. As it stated in the comment to this dialect:

> Use "hibernate.dialect.storage_engine=innodb" environment variable or JVM system property instead.

Using this dialect can also lead to mapping problems with date/time data types. See for example this.

答案2

得分: 0

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

此外,您还可以使用快捷键替换所有出现的任何语句,并进行全部替换。

英文:

If you are using Intellij as ide, you can modify the method signature and then provide a default value while changing the signature.

Also you can replace all occurrences of the any statement by using shortcut key and replace all.

huangapple
  • 本文由 发表于 2020年9月11日 18:26:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/63845257.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定