当调用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;
...
从代码中可以看到,我在@Column
注解中使用了insertable = false, updatable = false
,因此我希望在实际的SQL语句中忽略ts
。
@Override
@Transactional(readOnly = false)
public Reading save(Reading r) {
return readingRepository.save(r);
}
ReadingRepository 基本上是扩展了 Spring 的 CrudRepository,它有一个 save(...)
方法。
当我使用 ts=null
保存 Reading 对象时,从 Postgres 中得到错误:
ERROR: null value in column "ts" violates not-null constraint
因为 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)
为什么这个字段没有被忽略?
如果你问我我的数据库模式是否没问题,我会回答是的。当我在控制台中键入SQL查询时,没有ts的情况下一切正常。我甚至尝试了@Generated
和@GeneratedValue
注释。Name和ts都形成了表的主键,然而,即使我只将它们中的一个设置为PK,或者添加额外的代理ID列,结果仍然相同......
我是否漏看了什么,还是Spring框架可能存在缺陷?我使用的是Spring 5.1.2和SpringData 2.1.2。
注意:如果我使用@Transient
注释,则可以正确持久化插入查询,但是该字段在读取/提取时完全被忽略。
非常感谢您对此的任何帮助!
@IdClass
怎么可能与实体类相同? - M. Deinum@IdClass
,这样我就可以在这里有两个@Id
。正如我所提到的,当我删除它时,错误仍然存在。 - user3732445@IdClass
的作用,但它应该是一个独立的类而不是指向实体。此外,需要插入一个未生成的@Id
(你需要指定)。所以基本上你的映射是冲突的。你不想要一个生成的值,但也不想将其插入。因此,Hibernate需要做出决策。 - M. Deinum@Transient
,因为我需要能够获取和读取该值。 - user3732445