休眠错误:此类的ID必须在调用save()之前手动分配:


70
由以下原因引起:org.springframework.orm.hibernate3.HibernateSystemException:此类的ID必须在调用save()之前手动分配:com.rfid.model.Role; 嵌套的异常是org.hibernate.id.IdentifierGenerationException:此类的ID必须在调用save()之前手动分配:com.rfid.model.Role
    在org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:676)
    在org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
    在org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
    在org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
    在org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:748)
    在com.wfos.engine.wrapper.domain.impl.WrapperImpl.save(WrapperImpl.java:159)
    ...更多47
    由以下原因引起:org.hibernate.id.IdentifierGenerationException:此类的id必须在调用save()之前手动分配:com.rfid.model.Role
    在org.hibernate.id.Assigned.generate(Assigned.java:53)
    在org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
    在org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
    在org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
    在org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
    在org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    在org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
    在org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
    在org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673)
    在org.springframework.orm.hibernate3.HibernateTemplate $ 16.doInHibernate(HibernateTemplate.java:751)
    在org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
    ...另外50
    WARN [21:14:21](CommonsLoggingOutput.java:59):--错误:batchId [1]消息[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;
}

}

Answers:


106

您的@Entity班级String@Id字段具有类型,因此无法为您生成ID。

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

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

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


7
我不见了:@GeneratedValue(strategy = GenerationType.IDENTITY)。它帮助了我。
sns 2014年

1
OP应该将其标记为正确答案。我的其他实体没有@GeneratedValue批注,但它们可以工作,只需将其添加到一个实体中即可。奇怪的。但是无论如何,谢谢!
Jero Dungog

感谢你的回答。另外,它不一定必须Long在Java中,它可以是Integer
Jonathan Lee

4

对于休眠,当您要持久/保存对象时,知道您的对象将具有一个ID很重要。因此,请确保

    private String U_id;

当您要保留对象时,它将具有一个值。您可以通过@GeneratedValue注释或手动分配值来实现。

在您需要或想要手动分配ID的情况下(这实际上就是上面的错误),我希望至少将字段的值传递给构造函数U_id,例如,例如

  public Role (String U_id) { ... }

这样可以确保在实例化对象之前,该对象具有ID。我不知道您的用例是什么,以及您的应用程序如何并行运行,但是,在某些情况下,不建议这样做。您需要确保您的ID是唯一的。

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


4

使用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;

对我来说,这unique = true, nullable = false是必需的,因为DB模式就是这样。仅指定@Id@GeneratedValue对我不起作用。谢谢。
萨比尔·汗

3

这是我通过两种方法解决的问题:

  1. 将ID列设为int类型

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

  3. @GeneratedValue(strategy=GenerationType.SEQUENCE)如果可能的话尝试使用

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.