使用 JPA 跳过有关 INSERT 的专栏
Skip a column on INSERT with JPA
我有一个 JPA/EclipseLink 模型,其中包含多个参数,这些参数的值由 PostgreSQL 数据库设置为默认值。具体来说,我有:
- 类型为
SERIAL
的 id
列在添加新行时自动递增
- 类型为
TIMESTAMP
的 created_at
列,默认为 now()
我的模型是这样的:
import javax.persistence.*;
@Entity
@Table(name="entity")
@NamedQuery(name="Entity.findAll", query="SELECT e from Entity e")
public class Entity {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name="created_at")
private java.sql.Timestamp createdAt;
// constructor, getters, and setters
}
当我尝试在 javax.persistence.EntityManager
中插入带有 persist()
的行时,插入失败,因为正在为 created_at
列设置 NULL
值。我不想插入 NULL
,而是想简单地不向该列插入任何内容,并允许 PostgreSQL 将其设置为 now()
。本质上,我想在 createdAt
上使用 @GeneratedValue
,但该注释仅用于主键,不能用于多个属性。我可以使用另一个注释来完成这个吗?
您可能需要 insertable=false
在 Column
注释中:
@Column(name="created_at", insertable=false)
private java.sql.Timestamp createdAt;
发件人:http://docs.oracle.com/javaee/5/api/javax/persistence/Column.html
boolean insertable
(Optional) Whether the column is included in SQL INSERT statements generated by the persistence provide
如另一个答案中所述,如果您将插入值标记为 insertable=true(默认值),JPA 提供程序将在插入时设置该值。许多提供程序都会发生这种情况,即使为 null,因为它允许语句重用。
只是将其从语句中排除可能不是您想要的,因为在您的实体(和缓存)中具有值将需要刷新。 EclipseLink 虽然有 @ReturningInsert 允许 EclipseLink 使用数据库中的值更新实体。不幸的是,仅支持 Oracle - 其他数据库需要使用存储过程来 return 运行 插入和 return 值。
您可以在实体 class 上添加 @DynamicInsert
。如果没有此注释,插入语句将包含空字段。另外,可以在执行update语句的时候加上@ DynamicUpdate
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name="entity")
@NamedQuery(name="Entity.findAll", query="SELECT e from Entity e")
public class Entity {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name="created_at")
private java.sql.Timestamp createdAt;
// constructor, getters, and setters
}
我有一个 JPA/EclipseLink 模型,其中包含多个参数,这些参数的值由 PostgreSQL 数据库设置为默认值。具体来说,我有:
- 类型为
SERIAL
的id
列在添加新行时自动递增 - 类型为
TIMESTAMP
的created_at
列,默认为now()
我的模型是这样的:
import javax.persistence.*;
@Entity
@Table(name="entity")
@NamedQuery(name="Entity.findAll", query="SELECT e from Entity e")
public class Entity {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name="created_at")
private java.sql.Timestamp createdAt;
// constructor, getters, and setters
}
当我尝试在 javax.persistence.EntityManager
中插入带有 persist()
的行时,插入失败,因为正在为 created_at
列设置 NULL
值。我不想插入 NULL
,而是想简单地不向该列插入任何内容,并允许 PostgreSQL 将其设置为 now()
。本质上,我想在 createdAt
上使用 @GeneratedValue
,但该注释仅用于主键,不能用于多个属性。我可以使用另一个注释来完成这个吗?
您可能需要 insertable=false
在 Column
注释中:
@Column(name="created_at", insertable=false)
private java.sql.Timestamp createdAt;
发件人:http://docs.oracle.com/javaee/5/api/javax/persistence/Column.html
boolean insertable (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provide
如另一个答案中所述,如果您将插入值标记为 insertable=true(默认值),JPA 提供程序将在插入时设置该值。许多提供程序都会发生这种情况,即使为 null,因为它允许语句重用。
只是将其从语句中排除可能不是您想要的,因为在您的实体(和缓存)中具有值将需要刷新。 EclipseLink 虽然有 @ReturningInsert 允许 EclipseLink 使用数据库中的值更新实体。不幸的是,仅支持 Oracle - 其他数据库需要使用存储过程来 return 运行 插入和 return 值。
您可以在实体 class 上添加 @DynamicInsert
。如果没有此注释,插入语句将包含空字段。另外,可以在执行update语句的时候加上@ DynamicUpdate
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name="entity")
@NamedQuery(name="Entity.findAll", query="SELECT e from Entity e")
public class Entity {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name="created_at")
private java.sql.Timestamp createdAt;
// constructor, getters, and setters
}