问题描述
让我们假设我有一个Timestamp类型的主键ts
.该字段是在插入PostgreSQL表时自动生成的.我想告诉JPA/休眠不要发送或填充该字段,但是当实体被持久保存时,只需忽略它即可.
Let's suppose I have a primary key ts
of type Timestamp. That field is generated automatically on insert into my PostgreSQL table. I want to tell JPA/Hibernate not to send or populate that field but just ignore it when the entity is being persisted.
...
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "mygenerator")
@TableGenerator(name = "mygenerator", table = "ms.time_series")
@Column(name = "ts", insertable = false, updatable = false, columnDefinition= "TIMESTAMP WITHOUT TIME ZONE")
private Timestamp ts;
...
我无法使它正常工作.看来@Id
和@Columns(insertable = false, updatable = false)
不能一起工作,该设置已被忽略,并且框架试图以任何方式修改或发送该值.
I cannot get it to work. It looks like the @Id
and @Columns(insertable = false, updatable = false)
don't work together, that setting is being ignored and the framework is trying to modify or send the value in anyways.
我正在将最新的Spring 5和Spring Data 2.1.2与Hibernate一起使用.数据库是PostgreSQL.
I am using the latest Spring 5 and Spring Data 2.1.2 with Hibernate. Database is PostgreSQL.
推荐答案
在映射关系对象时,我们可以选择定义如何处理主键:如果要携带应用程序到应用程序以定义该单个值(当我们仅声明@Id
批注时),或者如果我们要将此责任留给持久性提供程序(当我们还声明@GeneratedValue
批注时).
At the moment of mapping the relational object, we have the option to define how we are going to treat the primary keys: if we are going to bring the application to the application to define this single value (when we declare only the @Id
annotation ), or if we are going to leave this responsibility with the persistence provider (when we also declare the @GeneratedValue
annotation ).
在引用术语持久性提供程序"时,请知道我们正在引用所选的框架,以便应用程序可以与数据库进行通信.例如Hibernate,EclipseLink和OpenJPA.
When citing the term persistence provider, know that we are referencing the chosen framework so that the application can communicate with the database. Some examples are Hibernate, EclipseLink and OpenJPA.
GenerationType.AUTO
是默认的生成类型,让持久性提供程序选择生成策略.
The GenerationType.AUTO
is the default generation type and lets the persistence provider choose the generation strategy.
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
GenerationType.IDENTITY
从性能的角度来看, GenerationType.IDENTITY
是最容易使用的,但不是最佳的.它依靠自动递增的数据库列,并允许数据库在每次插入操作时生成一个新值.从数据库的角度来看,这是非常有效的,因为对自动增量列进行了高度优化,并且不需要任何其他语句.
GenerationType.IDENTITY
The GenerationType.IDENTITY
is the easiest to use but not the best one from a performance point of view. It relies on an auto-incremented database column and lets the database generate a new value with each insert operation. From a database point of view, this is very efficient because the auto-increment columns are highly optimized, and it doesn’t require any additional statements.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
GenerationType.SEQUENCE
GenerationType.SEQUENCE
是我首选的生成主键值并使用数据库序列生成唯一值的方法.
GenerationType.SEQUENCE
The GenerationType.SEQUENCE
is my preferred way to generate primary key values and uses a database sequence to generate unique values.
它需要附加的select语句才能从数据库序列中获取下一个值.但这对大多数应用程序没有性能影响.而且,如果您的应用程序必须保留大量的新实体,则可以使用一些特定于Hibernate的优化来减少语句的数量.
It requires additional select statements to get the next value from a database sequence. But this has no performance impact for most applications. And if your application has to persist a huge number of new entities, you can use some Hibernate specific optimizations to reduce the number of statements.
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
GenerationType.TABLE
GenerationType.TABLE
如今很少使用.它通过在数据库表中存储和更新其当前值来模拟序列,这需要使用悲观锁,该悲观锁将所有事务按顺序排列.这会减慢您的应用程序的速度,因此,如果数据库支持大多数流行的数据库所支持的序列,则您最好使用 GenerationType.SEQUENCE
.
GenerationType.TABLE
The GenerationType.TABLE
gets only rarely used nowadays. It simulates a sequence by storing and updating its current value in a database table which requires the use of pessimistic locks which put all transactions into a sequential order. This slows down your application, and you should, therefore, prefer the GenerationType.SEQUENCE
, if your database supports sequences, which most popular databases do.
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
建议:
@Id
@GeneratedValue(strategy=GenerationType.TABLE)
@Column(name = "ts", columnDefinition = "TIMESTAMP WITHOUT TIME ZONE",
insertable = false, updatable = false)
private Timestamp ts;
参考:
- https://www.thoughts-on-java. org/jpa-generate-primary-keys/
- https://vladmihalcea.com/why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate/
- https://www.thoughts-on-java.org/jpa-generate-primary-keys/
- https://vladmihalcea.com/why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate/
Reference:
这篇关于如何设置JPA注释以在数据库级别生成ID(主键)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!