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 允许从触发器取回值。