【发布时间】:2019-04-16 02:21:30
【问题描述】:
我希望在调用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 的错误:
错误:“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 注释。 Name 和 ts 都构成了表的主键,但是,如果我只将其中一个设为 PK 或添加额外的代理项,结果是相同的标识列。结果一样...
我是否忽略了某些东西,或者 Spring 框架中是否存在错误??我使用的是 Spring 5.1.2 和 SpringData 2.1.2
注意:如果我使用 @Transient 注释可以正确保留插入查询,但即使在读取/获取时,该字段也会被完全忽略。
非常感谢您对此提供的任何帮助!
【问题讨论】:
-
在您的 Timestamp 字段上使用 @Transient 注释。
-
如果它不可插入或不可更新,它怎么可能是
null?另外你的映射很奇怪@IdClass怎么能和实体类一样? -
@M.Deinum 我必须添加
@IdClass,这样我才能在这里有两个@Ids。正如我所提到的,当我删除该错误仍然存在。 -
我知道
@IdClass的用途,但它应该是一个单独的类,而不是指向实体。还需要插入未生成的@Id(您需要指定)。所以基本上你的映射是冲突的。您不想要生成的值,但不想将其插入为。所以hibernate需要做出决定。 -
@AngadBansode 请阅读我的帖子,我不能使用
@Transient,因为我需要能够获取并读取该值
标签: java spring hibernate jpa spring-data-jpa