【问题标题】:Spring Data JPA JpaRepository.save(entity) not returning database default valuesSpring Data JPA JpaRepository.save(entity) 不返回数据库默认值
【发布时间】:2014-12-24 10:28:32
【问题描述】:

我有一个相当简单的问题。在单个事务中,我的代码如下所示:

MyClass c = new MyClass();
c.setPropA("A");

c = myClassRepository.save(c);

c.setPropC("C");

我的实体如下所示:

@Entity
@Table(name = "MY_CLASS")
public class MyClass {
  private String propA;
  private String propB;
  private String propC;

  @Id
  @Column(name = "PROP_A", unique = true, nullable = false, updatable = false)
  public String getPropA() { return propA; }
  public void   setPropA(String propA) { this.propA = propA; }

  @Column(name = "PROP_B", insertable = false)
  public String getPropB() { return propB; }
  public void   setPropB(String propB) { this.propB = propB; }

  @Column(name = "PROP_C")
  public String getPropC() { return propC; }
  public void   setPropC(String propC) { this.propC = propC; }
}

并且数据库是这样设置的(方言=Oracle 11G)

CREATE TABLE MY_CLASS {
  PROP_A VARCHAR2 NOT NULL PRIMARY KEY,
  PROP_B VARCHAR2 DEFAULT 'B' NOT NULL,
  PROP_C VARCHAR2
}

因此,基于持久化实体的代码,我想我会得到如下所示的查询:

MyClass c = new MyClass();
c.setPropA("A");

c = myClassRepository.saveAndFlush(c);
// INSERT INTO MY_CLASS (PROP_A, PROP_C) VALUES ("A", NULL)
// SELECT PROP_A, PROP_B, PROP_C FROM MY_CLASS -- to refresh `c`

c.setPropC("C");

// After transaction ends, flush change to `c.propC`
// UPDATE MY_CLASS SET PROP_B = "B", PROP_C = "C" WHERE PROP_A = "A"

...但是SELECT 永远不会发生。为什么实体没有刷新?

因为UPDATE(立即)跟在INSERTc.propB 之后,所以这会中断,c.propB 仍然是null。我得到一个ORA-01407: cannot update ("MY_SCHEMA"."MY_CLASS"."PROP_B") to NULL 堆栈跟踪。

我意识到在 Java 中使用@PrePersist 或在columnDefinition 上设置默认值可以解决这个问题,但我不应该重复默认值。

注意:这在我使用 org.hibernate.Session.saveOrUpdate() 而不是 Spring Data JPA 进行此操作之前有效。

提前感谢您的帮助!

【问题讨论】:

    标签: java spring oracle hibernate jpa


    【解决方案1】:

    Hibernate 不知道 B 是由数据库生成的,并且它必须在插入后读取它,除非您使用 @Generated annotation 告诉它这样做。

    【讨论】:

    • 好收获! @GeneratedValue 会是 JPA 的等价物吗?
    • 就我而言,我有一列modified_at,默认值为当前日期时间。唯一对我有用的是@UpdateTimestamp。我不需要打电话给.flush()@Generated@GeneratedValue 注释都不适合我,即使在使用 .flush() 之后,该字段在 .save() 之后仍会返回为 null。
    猜你喜欢
    • 2015-07-31
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 2014-11-03
    相关资源
    最近更新 更多