我在一个基于Oracle DB和EclipseLink的项目中作为EM实现。
我有一个有标准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"。
我的问题是:对于同一@Sequencegenerator
的非@TableGenerator
字段,是否也可以利用@Id
和entity
注释?
我不是一个触发粉丝...所以在假设的第一个片段中添加这样的东西......我可以使用JPA
标准注释管理整个实体:
@GeneratedValue(strategy = GenerationType.TABLE, generator = "UNIQUEFIELD")
@TableGenerator(name = "UNIQUEFIELD", allocationSize = 1)
@Column
private String uniqueValuesField;
谢谢!
答案 0 :(得分:0)
要将属性标记为已生成,请使用特定于Hibernate的@Generated注释。标记为已生成的属性必须另外是不可插入且不可更新的。只有@Version和@Basic类型可以标记为已生成。 http://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#mapping-generated
never (the default)
在数据库中不生成给定的属性值。
insert
给定的属性值是在insert上生成的,但在后续更新时不会重新生成。像creationTimestamp这样的属性属于这个类别。
always
在插入和更新时都会生成属性值。
答案 1 :(得分:0)
我认为编写触发器是一种冗余操作,它会降低代码的可读性。 在休眠TABLE,SEQUENCE和IDENTITY中提供了三种主要类型的ID生成器。
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;
}
}
答案 2 :(得分:0)
JPA不支持非id字段上的序列,因此如果不依赖或深入研究提供者的本机支持,这种方法就不可行。
如果需要获取触发器设置的值,您可以随后刷新实体,但它们在遗留系统上很常见,因此提供者将支持某种形式的触发器。 EclipseLink具有@ReturnInsert和@ReturnUpdate以允许从触发器获取值。