让我们假设我有一个时间戳类型为ts
的主键。该字段是在插入我的PostgreSQL表时自动生成的。我想告诉JPA /休眠不要发送或填充该字段,但是当实体被持久保存时,只需忽略它即可。
...
@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)
似乎无法一起使用,该设置已被忽略,并且框架试图以任何方式修改或发送该值。
我在Hibernate中使用最新的Spring 5和Spring Data 2.1.2。数据库是PostgreSQL。
答案 0 :(得分:0)
在映射关系对象时,我们可以选择定义如何处理主键:如果我们要将应用程序带到应用程序来定义此单个值(当我们仅声明@Id
注释),或者如果我们要将此责任留给持久性提供者(当我们还声明@GeneratedValue
注释时)。
在引用术语“持久性提供程序”时,要知道我们正在引用所选的框架,以便应用程序可以与数据库进行通信。例如Hibernate,EclipseLink和OpenJPA。
GenerationType.AUTO
是默认的生成类型,让持久性提供程序选择生成策略。
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
从性能的角度来看, GenerationType.IDENTITY
是最容易使用的,但不是最佳的。它依靠自动递增的数据库列,并允许数据库在每次插入操作时生成一个新值。从数据库的角度来看,这是非常有效的,因为对自动增量列进行了高度优化,并且不需要任何其他语句。
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
GenerationType.SEQUENCE
是我首选的生成主键值并使用数据库序列生成唯一值的方法。
它需要附加的select语句才能从数据库序列中获取下一个值。但这对大多数应用程序没有性能影响。而且,如果您的应用程序必须保留大量的新实体,则可以使用一些特定于Hibernate的优化来减少语句的数量。
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
GenerationType.TABLE
如今很少使用。它通过在数据库表中存储和更新其当前值来模拟序列,这需要使用悲观锁,该悲观锁将所有事务按顺序排列。这会减慢您的应用程序的速度,因此,如果您的数据库支持大多数流行的数据库所支持的序列,则您最好使用 GenerationType.SEQUENCE
。
@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;