【问题标题】:JPA does not return default value after savingJPA 保存后不返回默认值
【发布时间】:2020-08-18 10:33:22
【问题描述】:

我遇到了一个问题。 A 有一个实体:

@Entity
@Table(name = "user")
public class User {

  @Id
  @GeneratedValue
  private Integer id;

  @Column(name = "date_create", insertable = false, updatable = false, nullable = false)
  private Date dateCreate;

}

相关表的DDL:

CREATE TABLE user (
  id SERIAL PRIMARY KEY,
  date_create TIMESTAMP NOT NULL DEFAULT now()
);

我有这样的逻辑:

@Service
public class Service1 {

  @Autowired
  private UserRepository userRepository;

  @Transactional
  public User createUser() {
    return userRepository(new User());
  }
 }

 @Service
 public class Service2 {

   @Autowired
   private Service1 service1;

   public void createUser() {
     User createdUser = service1.createUser();
     System.out.println(createdUser.getDateCreate()); // actual result : null
   }
  }

字段 dateCreate 由 DB 函数 now() 设置,但 JPA 在创建的实体中不返回它。

有人知道如何解决这个问题吗?不使用 Hibernate 或 Spring 特定工具。只是 JPA。

【问题讨论】:

  • 您需要从数据库中刷新实体,否则它将无法工作。
  • 我使用了 'saveAndFlush' 但它没有帮助(我可以在不调用其他查询的情况下获取实际的实体数据吗?
  • createdUser = userRepository.saveAndFlush(createdUser);?
  • 如前所述使用刷新(这是实体管理器上的实际方法)。
  • 'saveAndFlush' 没有帮助我(从 EntityManager 刷新做到了!谢谢!

标签: java spring postgresql jpa spring-data-jpa


【解决方案1】:

你需要将数据保存到数据库后refresh获取对象的最新状态,如entityManager.refresh(createdUser)

您可以如下所述使用它。

 @Service
 public class Service2 {

   @Autowired
   private Service1 service1;

   @PersistenceContext
   private EntityManager entityManager;

   public void createUser() {
     User createdUser = service1.createUser();
     entityManager.refresh(createdUser);
     System.out.println(createdUser.getDateCreate()); // actual result : null
   }
}

【讨论】:

    【解决方案2】:

    您可以使用注解@PrePersist 在持久化之前创建日期。

        @Entity
        @Table(name = "user")
        public class User {
        
              @Id
              @GeneratedValue
              private Integer id;
            
              @Column(name = "date_create")
              @Temporal(TemporalType.TIMESTAMP)
              private Date dateCreate;
    
    
              @PrePersist
              private void onCreate() {
              dateCreate= new Date();
             }
            
            }
    

    【讨论】:

    • 感谢您的回答!我想过这个问题。但是我们在 DDL 中使用了 'default now()' 并且我们依赖它。可能有其他解决方案可以返回实际的“dateCreate”值吗?我使用了 Hibernate 的 @CreationTimestamp,它运行良好。但我不想与特定的 JPA 实现特性捆绑在一起。
    • 更新后可以尝试调用方法refresh。顺便说一句,@PrePersist 注释是 JPA 标准规范的一部分,不是特定于供应商的。
    【解决方案3】:
    @Entity
    @Table(name = "user")
    public class User {
    
      @Id
      @GeneratedValue
      private Integer id;
    
      @Column(name = "date_create", insertable = false, updatable = false, nullable = false)
      private LocaleDate dateCreate;
    
    }
    

    private LocaleDateTime dateCreate;
    
    1. Lo​​caleDate 是将日期存储到数据库中,没有时间。
    2. Lo​​caleDateTime 是将日期和时间存储到数据库中。

    【讨论】:

      猜你喜欢
      • 2015-07-31
      • 1970-01-01
      • 2014-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-27
      • 2012-11-03
      • 2019-02-22
      相关资源
      最近更新 更多