简体   繁体   English

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

[英]JPA Annotation @Column(insertable=false) is being ignored, why?

I want one of the fields to be ignored when called save() method. 我想在调用save()方法时忽略其中一个字段。 The field is gonna get populated automatically by the database and returned. 该字段将由数据库自动填充并返回。 It should be treated as a read-only field. 它应该被视为只读字段。

I am concerned about private Timestamp ts; 我担心private Timestamp ts; field: 领域:

@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;
   ...

As you see, I use insertable = false, updatable = false are inside the @Column annotation, so I'd expect that ts is ignored when forming the actual SQL behind the curtain. 如您所见,我在@Column注释中使用了insertable = false, updatable = false ,所以我希望在窗帘后面形成实际的SQL时会忽略ts

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

ReadingRepository is basically extended Spring's CrudRepository which has save(...) method. ReadingRepository基本上扩展了Spring的CrudRepository ,它具有save(...)方法。

When I save Reading object with ts=null I get an error from Postgres: 当我用ts=null保存Reading对象时,我从Postgres得到一个错误:

ERROR: null value in column "ts" violates not-null constraint 错误:“ts”列中的空值违反了非空约束

because Spring Data did not actually ignore the ts field based what I see from the log : 因为我从日志中看到的 Spring Data实际上没有忽略ts字段:

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

Clearly, I want the query to be without ts like this: 很显然,我希望查询是没有这样的TS:

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

Why is the field not being ignored? 为什么这个领域不被​​忽视?

Now if you ask me whether my database schema is okay I say yes. 现在,如果你问我数据库模式是否正常,我说是的。 When I type SQL query in console without the ts everything is fine. 当我在没有ts的控制台中键入SQL查询时,一切都很好。 I even tried @Generated and @GeneratedValue annotations. 我甚至尝试过@Generated@GeneratedValue注释。 Name and ts are both forming a primary key for the table, however, the result is the same if I make only one of them a PK or if I add an extra surrogate ID column. 名称ts都是表格的主键,但是,如果我只将其中一个作为PK或者添加额外的代理ID列,结果是相同的。 Same result... 结果相同......

Am I overlooking something or is there maybe a bug in the Spring framework?? 我忽略了什么,或者Spring框架中是否有错误? I am using Spring 5.1.2 and SpringData 2.1.2 我使用的是Spring 5.1.2和SpringData 2.1.2

Note: If I use @Transient annotation that persists the insert query correctly but then the field is being ignored completely even on read/fetch. 注意:如果我使用@Transient注释正确地保持插入查询,那么即使在读取/获取时也会完全忽略该字段。

Many thanks for any help with this! 非常感谢您的帮助!

Try using GenericGenerator and GeneratedValue in your code. 尝试在代码中使用GenericGeneratorGeneratedValue

Add the needed annotation and give values to all other members in Reading class, except ts. 添加所需的注释并为Reading类中的所有其他成员提供值,但ts除外。

Here some examples . 这里有一些例子

As you say 正如你所说

I get an error from Postgres 我从Postgres得到一个错误

If you check the docs it states: 如果您查看文档,则说明:

Technically, a primary key constraint is simply a combination of a unique constraint and a not-null constraint. 从技术上讲,主键约束只是唯一约束和非空约束的组合。

That's also true for multi-column primary keys (see here ) 对于多列主键也是如此(参见此处

So, if ts is part of your primary key in the database (as the @Id indicates) it's simply not possible to insert null values in that column. 因此,如果ts是数据库中主键的一部分(如@Id所示),则根本无法在该列中插入空值。

IMO Hibernate/Spring got nothing to do with that as IMO Hibernate / Spring与此毫无关系

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

should be equivalent to 应该相当于

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM