JPA注释@Column(insertable = false)被忽略,为什么?

时间:2018-11-13 09:31:43

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

我希望在调用save()方法时忽略其中一个字段。该字段将由数据库自动填充并返回。应该将其视为只读字段。

我担心private Timestamp ts;字段:

@Entity
@Table(name = "time_series", schema = "ms")
@IdClass(Reading.class)
public class Reading implements Serializable {

   private static final long serialVersionUID = 1L;

   @Id
   @Column(name = "name", nullable = false)
   private String sensorName;

   @Id
   @Column(name = "ts", insertable = false, updatable = false)
   private Timestamp ts;

   @Column(name = "reading")
   private Double value;
   ...

如您所见,我在insertable = false, updatable = false批注内使用@Column,所以我希望在幕后形成实际SQL时会忽略ts

@Override
@Transactional(readOnly = false)
public Reading save(Reading r) {        
    return readingRepository.save(r);
}

ReadingRepository 基本上是Spring的 CrudRepository 的扩展,它具有save(...)方法。

当我用ts=null保存 Reading 对象时,我从Postgres得到了一个错误:

  

错误:列“ ts”中的空值违反了非空约束

因为Spring Data实际上并没有忽略基于我从日志中看到的内容 ts 字段:

insert into ms.time_series (ts, name, reading) values (NULL, 'sensor1', 10.0)

很明显,我希望查询不包含 ts ,如下所示:

insert into ms.time_series (name, reading) values ('sensor1', 10.0)

为什么不忽略该字段?

现在,如果您问我我的数据库架构是否还好,我会说是。当我在没有ts的控制台中键入SQL查询时,一切都很好。我什至尝试了@Generated@GeneratedValue注释。 名称 ts 都构成了该表的主键,但是,如果我只将其中一个做为PK或添加一个额外的代理,则结果是相同的ID列。结果相同...

我是在俯视什么还是在Spring框架中出现错误?我正在使用Spring 5.1.2和SpringData 2.1.2

注意:如果我使用@Transient注释正确地保留了插入查询,但是即使在读取/获取时,该字段也将被完全忽略。

非常感谢您对此提供的帮助!

2 个答案:

答案 0 :(得分:0)

尝试在代码中使用GenericGeneratorGeneratedValue

添加所需的注释,并将值赋给Reading类中的所有其他成员(ts除外)。

这里有examples

答案 1 :(得分:-1)

如你所说

  

我从Postgres收到一个错误

如果您选中docs,则会显示:

  

从技术上讲,主键约束只是唯一约束和非空约束的组合。

对于多列主键也是如此(请参见here

因此,如果return $this->render('anulacion', ['model' => $model = new Turnosservice()]); 是数据库中主键的一部分(如ts所示),则根本无法在该列中插入空值。

IMO Hibernate / Spring与之无关

@Id

应等效于

insert into ms.time_series (ts, name, reading) values (NULL, 'sensor1', 10.0)