Hibernate使用数据库触发器填充主键

时间:2013-02-27 16:09:57

标签: java hibernate jpa oracle10g jpa-2.0

我在Spring 3中使用Hibernate 4.1.0.Final

我在实体类

中有以下内容
@Id
@Column(name = "PROJECT_NO")
@GeneratedValue(strategy=GenerationType.TABLE)
private String projectNumber;

是否可以使用数据库触发器来填充表的主键?或者我必须为此使用CustomGenerator?

当我尝试上述操作时,我遇到以下异常

org.hibernate.id.IdentifierGenerationException: Unknown integral data type
for ids : java.lang.String

数据库触发器没有任何序列,它正在使用

SELECT NVL (MAX (project_no), 0) + 1 FROM projects

编辑1

@GeneratedValue(generator="trig")
@GenericGenerator(name="trig", strategy="select", 
parameters=@Parameter(name="key", value="projectNo"))

以上引发了以下异常

Hibernate: select PROJECT_NO from PROJECTS where PROJECT_NO =?

java.lang.NullPointerException
exception in save null
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValue(AbstractEntityTuplizer.java:645)
    at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValue(AbstractEntityPersister.java:4268)
    at org.hibernate.id.SelectGenerator$SelectGeneratorDelegate.bindParameters(SelectGenerator.java:138)
    at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:84)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2764)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3275)
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)

2 个答案:

答案 0 :(得分:3)

问题是你使用的是String而不是数值。使用Long而不是String,您的错误将消失。

AFAIK,您无法使用触发器来填充ID。实际上,Hibernate必须检索生成的ID,但由于它没有ID,我不知道它如何读回它刚插入的行(鸡和鸡蛋问题)。

您可以在插入行之前使用SQL查询获取ID,但此策略效率低,并且在并发插入的情况下存在重复ID的风险。所以我不会使用这个策略。您使用Oracle标记了您的帖子。我建议你使用序列。这就是他们的目的。

答案 1 :(得分:2)

关于Hibernate 3.3 documentation page,你可以这样做。

  

选择

     

通过选择检索由数据库触发器分配的主键   行由一些唯一键和检索主键值。