Jpa 2.0 和唯一约束
Jpa 2.0 and Unique Constraints
我在一个基于 Oracle DB 和 EclipseLink 作为 EM 实现的项目中。
我有一个 table,它有一个标准的 id 序列生成器,比方说:
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "INVOICE")
@TableGenerator(name = "INVOICE", allocationSize = 1, table = Constants.SEQUENCE_TABLE, schema = Constants.DATABASE_SCHEMA)
@Column(length = 40)
private String id;
我还有一个唯一的数字字段。我决定为该字段创建一个特殊序列,并通过触发器填充它,触发器在每次插入时增加该数字字段,传递序列 "NextVal".
我的问题是:对于同一个 [=15= 不是 @Id
的字段,利用 @Sequencegenerator
和 @TableGenerator
注释是否是一种好的做法]?
我不是触发器迷...所以从假设的第一个片段中添加这样的东西...我可以使用 JPA
标准注释来管理整个实体:
@GeneratedValue(strategy = GenerationType.TABLE, generator = "UNIQUEFIELD")
@TableGenerator(name = "UNIQUEFIELD", allocationSize = 1)
@Column
private String uniqueValuesField;
谢谢!
To mark a property as generated, use The Hibernate specific @Generated annotation.Properties marked as generated must additionally be non-insertable and non-updateable. Only @Version and @Basic types can be marked as generated.
http://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#mapping-generated
never (the default)
给定的 属性 值不是在数据库中生成的。
insert
给定的 属性 值在插入时生成,但不会在后续更新时重新生成。 creationTimestamp 等属性属于此类。
always
属性 值在插入和更新时生成。
希望对您有所帮助。
我觉得写触发器是多余的动作,会降低代码的可读性。
hibernate中提供了三种主要的ID生成器TABLE、SEQUENCE和IDENTITY.
here 是一本很好的读物,其中包含 Vladmihalcea 提供的有关序列生成器策略的示例。
或者你可以创建自己的序列生成器,我必须在两个表中保留一个唯一的 ID,所以我这样做了
@Id
@GenericGenerator(name = "sequence", strategy = "IdGenerator")
@GeneratedValue(generator = "sequence")
@Column(name = "ID", columnDefinition = "BIGINT")
并在 ID 生成器中
Public class IdGenerator extends IncrementGenerator {
private static long nextVal = Long.MIN_VALUE;
private static Object idlock = new Object();
private static volatile String COLUMN_NAME = "id";
@Override
public Serializable generate(SessionImplementor session, Object obj) {
if (obj == null) {
throw new HibernateException("Null object passed");
}
synchronized (idlock) {
nextVal = //get the value according to your logic
}
return nextVal;
}
}
JPA 不支持非 id 字段上的序列,因此如果不依赖或深入研究您的提供商的本机支持,这不太可能起作用。
如果需要获取触发器设置的值,您可以随时刷新实体,但它们在遗留系统上很常见,因此提供商将支持某种形式的触发器。 EclipseLink @ReturnInsert and @ReturnUpdate 允许从触发器取回值。
我在一个基于 Oracle DB 和 EclipseLink 作为 EM 实现的项目中。
我有一个 table,它有一个标准的 id 序列生成器,比方说:
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "INVOICE")
@TableGenerator(name = "INVOICE", allocationSize = 1, table = Constants.SEQUENCE_TABLE, schema = Constants.DATABASE_SCHEMA)
@Column(length = 40)
private String id;
我还有一个唯一的数字字段。我决定为该字段创建一个特殊序列,并通过触发器填充它,触发器在每次插入时增加该数字字段,传递序列 "NextVal".
我的问题是:对于同一个 [=15= 不是 @Id
的字段,利用 @Sequencegenerator
和 @TableGenerator
注释是否是一种好的做法]?
我不是触发器迷...所以从假设的第一个片段中添加这样的东西...我可以使用 JPA
标准注释来管理整个实体:
@GeneratedValue(strategy = GenerationType.TABLE, generator = "UNIQUEFIELD")
@TableGenerator(name = "UNIQUEFIELD", allocationSize = 1)
@Column
private String uniqueValuesField;
谢谢!
To mark a property as generated, use The Hibernate specific @Generated annotation.Properties marked as generated must additionally be non-insertable and non-updateable. Only @Version and @Basic types can be marked as generated. http://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#mapping-generated
never (the default)
给定的 属性 值不是在数据库中生成的。
insert
给定的 属性 值在插入时生成,但不会在后续更新时重新生成。 creationTimestamp 等属性属于此类。
always
属性 值在插入和更新时生成。
希望对您有所帮助。
我觉得写触发器是多余的动作,会降低代码的可读性。 hibernate中提供了三种主要的ID生成器TABLE、SEQUENCE和IDENTITY.
here 是一本很好的读物,其中包含 Vladmihalcea 提供的有关序列生成器策略的示例。
或者你可以创建自己的序列生成器,我必须在两个表中保留一个唯一的 ID,所以我这样做了
@Id
@GenericGenerator(name = "sequence", strategy = "IdGenerator")
@GeneratedValue(generator = "sequence")
@Column(name = "ID", columnDefinition = "BIGINT")
并在 ID 生成器中
Public class IdGenerator extends IncrementGenerator {
private static long nextVal = Long.MIN_VALUE;
private static Object idlock = new Object();
private static volatile String COLUMN_NAME = "id";
@Override
public Serializable generate(SessionImplementor session, Object obj) {
if (obj == null) {
throw new HibernateException("Null object passed");
}
synchronized (idlock) {
nextVal = //get the value according to your logic
}
return nextVal;
}
}
JPA 不支持非 id 字段上的序列,因此如果不依赖或深入研究您的提供商的本机支持,这不太可能起作用。
如果需要获取触发器设置的值,您可以随时刷新实体,但它们在遗留系统上很常见,因此提供商将支持某种形式的触发器。 EclipseLink @ReturnInsert and @ReturnUpdate 允许从触发器取回值。