Sping Boot JPA @UpdateTimestamp无法与Postgresql搭配使用

fdbelqdn  于 2022-11-14  发布在  PostgreSQL
关注(0)|答案(2)|浏览(167)

我遇到了一个奇怪的问题上次修改日期没有自动更新。我正在使用Postgresql版本12.3Springboot 2.2.4.RELEASE这是我的实体类

  1. @Entity
  2. @Table(name = "users")
  3. @org.hibernate.annotations.Entity(
  4. dynamicUpdate = true
  5. )
  6. @Data
  7. public class Users {
  8. @Id
  9. @GeneratedValue(generator = "UUID")
  10. @GenericGenerator(
  11. name = "UUID",
  12. strategy = "org.hibernate.id.UUIDGenerator"
  13. )
  14. @Column(updatable = false, nullable = false)
  15. private String userId;
  16. private String userName;
  17. private String userEmail;
  18. private String userPhoneNumber;
  19. @CreationTimestamp
  20. @Column(updatable = false)
  21. @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+05:30")
  22. private Timestamp createdOn;
  23. @UpdateTimestamp
  24. @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+05:30")
  25. private Timestamp lastUpdatedOn;
  26. }

数据库记录:

  1. createdon | lastupdatedon
  2. 2020-08-27 07:43:37.994 | 2020-08-27 07:43:37.994
  3. 2020-08-07 07:49:22.797 | 2020-08-07 07:49:22.797
  4. 2020-08-12 13:38:43.503 | 2020-08-12 13:38:43.503

您可以看到createdOn和lastUpdatedOn是相同的。即使经常更新记录,上次修改日期也不会更新。
我正在使用jpa存储库保存记录,例如:

  1. usersRepository.save(user);
pxyaymoc

pxyaymoc1#

您是否可以尝试使用PrePersist & PreUpdate注解而不是CreationTimestamp & UpdateTimestamp来对实体进行更多控制,并应用于以下内容-

  1. @Entity
  2. @Table(name = "users")
  3. @org.hibernate.annotations.Entity(
  4. dynamicUpdate = true
  5. )
  6. @Data
  7. public class Users {
  8. @Id
  9. @GeneratedValue(generator = "UUID")
  10. @GenericGenerator(
  11. name = "UUID",
  12. strategy = "org.hibernate.id.UUIDGenerator"
  13. )
  14. @Column(updatable = false, nullable = false)
  15. private String userId;
  16. private String userName;
  17. private String userEmail;
  18. private String userPhoneNumber;
  19. @Column(updatable = false)
  20. private Timestamp createdOn;
  21. @Column
  22. private Timestamp lastUpdatedOn;
  23. @PrePersist
  24. public void onInsert() {
  25. createdOn = Timestamp.from(ZonedDateTime.now(ZoneId.of("Asia/Kolkata")).toInstant());
  26. lastUpdatedOn = createdOn;
  27. }
  28. @PreUpdate
  29. public void onUpdate() {
  30. lastUpdatedOn = Timestamp.from(ZonedDateTime.now(ZoneId.of("Asia/Kolkata")).toInstant());
  31. }
  32. }
展开查看全部
fzwojiic

fzwojiic2#

您是否碰巧在事务中调用了保存方法?
时间戳在写入DB时填充,因此在提交事务 * 之后 * 才能看到它们的值。
当我遇到这个问题时,我的代码如下所示:

  1. @Transactional
  2. public Response createFooBusinessLogic(Foo foo) {
  3. var createdEntity = fooRepository.save(foo);
  4. return someMethodUsingCreatedTime(createdEntity);
  5. }

有两种解决方案:
1.如果数据库事务中的另一个实体需要日期,则可以使用saveAndFlush而不是save。这将强制写入数据库,返回创建和修改的日期。
1.否则,请将save调用重构为另一个方法,并使用@Transactional对该方法进行注解。
我选择了选项(2),如下所示:

  1. public Response createFooBusinessLogic(Foo foo) {
  2. var createdEntity = facade.saveFoo(foo);
  3. return someMethodUsingCreatedTime(createdEntity);
  4. }
  5. // In Facade.java
  6. @Transactional
  7. public Foo saveFoo(Foo foo) {
  8. return fooRepository.save(foo);
  9. }

请注意,要使事务注解正常工作,调用不能是自调用的(即必须在另一个类上调用),并且方法必须是公共的。

展开查看全部

相关问题