在调用save()之前,必须手动分配此类的ID:

时间:2012-06-12 13:16:37

标签: hibernate identifier

Caused by: org.springframework.orm.hibernate3.HibernateSystemException: ids for this class must be manually assigned before calling save(): com.rfid.model.Role; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.rfid.model.Role
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:676)
    at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
    at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
    at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:748)
    at com.wfos.engine.wrapper.domain.impl.WrapperImpl.save(WrapperImpl.java:159)
    ... 47 more
    Caused by: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.rfid.model.Role
    at org.hibernate.id.Assigned.generate(Assigned.java:53)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673)
    at org.springframework.orm.hibernate3.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:751)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
    ... 50 more
    WARN [21:14:21] (CommonsLoggingOutput.java:59): - --Erroring: batchId[1] message[java.lang.reflect.UndeclaredThrowableException]

我的班级是这样的:

@Entity
@javax.persistence.Table(name="Role")
@Table(appliesTo = "Role")
public class Role {

@Id  
@Column(name="U_id")
public String U_id;

public String U_pwd;

public String U_account;

public String U_mode;

public String U_status;


public String getU_pwd() {
    return U_pwd;
}

public void setU_pwd(String u_pwd) {
    U_pwd = u_pwd;
}

public String getU_account() {
    return U_account;
}

public void setU_account(String u_account) {
    U_account = u_account;
}

public String getU_id() {
    return U_id;
}

public void setU_id(String u_id) {
    U_id = u_id;
}

public String getU_mode() {
    return U_mode;
}

public void setU_mode(String u_mode) {
    U_mode = u_mode;
}

public String getU_status() {
    return U_status;
}

public void setU_status(String u_status) {
    U_status = u_status;
}

}

5 个答案:

答案 0 :(得分:76)

您的@Entity课程的String字段属于@Id类型,因此无法为您生成ID。

如果您将其更改为数据库中的自动增量和java中的Long,并添加@GeneratedValue注释:

@Id
@Column(name="U_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long U_id;

它将为您处理递增ID生成。

答案 1 :(得分:4)

对于hibernate,当你想要持久保存它时,知道你的对象会有一个id是很重要的。因此,请确保

    private String U_id;
当你要坚持你的对象时,

将有一个值。您可以使用@GeneratedValue注释或手动分配值来执行此操作。

如果你需要或想要手动分配你的id(这就是上面的错误实际上是什么),我宁愿将字段的值传递给你的构造函数,至少对于U_id,例如

  public Role (String U_id) { ... }

这确保您的对象具有id,直到您实例化它为止。我不知道您的用例是什么以及您的应用程序在并发中的行为方式,但在某些情况下不建议这样做。您需要确保您的ID是唯一的。

进一步说明:Hibernate仍然需要默认构造函数,如hibernate documentation中所述。为了使用默认构造函数阻止您(可能是其他程序员,如果您正在设计api)Role的实例化,只需将其声明为private

答案 2 :(得分:2)

以下是我通过两种方式解决的问题:

  1. 将ID列设为int类型

  2. 如果您在ID中使用 autogenerate ,则不会在ID设置器中分配值。如果您的映射有些,那么有时自动生成的ID不会被忽略。 (我不知道为什么)

  3. 尽可能使用@GeneratedValue(strategy=GenerationType.SEQUENCE)

答案 3 :(得分:2)

使用Oracle数据库中定义的序列ID解决了此问题。

ORACLE_DB_SEQ_ID被定义为表的序列。另请查看控制台以查看用于验证的Hibernate SQL。

@Id
@Column(name = "MY_ID", unique = true, nullable = false)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "id_Sequence")
@SequenceGenerator(name = "id_Sequence", sequenceName = "ORACLE_DB_SEQ_ID")
Long myId;

答案 4 :(得分:0)

当数字 id 值的类型不匹配时,H2 数据库出现此错误。通过 sql 语句的数量生成和填充表,并将 id 设置为 INT。后来创建了 Entity Java 类并将 id 设置为 Long。在 Java 类中调整 id 类型后问题已解决。