106
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]

My class is like this:

@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;
}

}
risingTide
  • 1,754
  • 7
  • 31
  • 60
程序猿
  • 1,061
  • 2
  • 7
  • 4

10 Answers10

162

Your @Entity class has a String type for its @Id field, so it can't generate ids for you.

If you change it to an auto increment in the DB and a Long in java, and add the @GeneratedValue annotation:

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

it will handle incrementing id generation for you.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 17
    I was missing: @GeneratedValue(strategy=GenerationType.IDENTITY). It helped me. – naeemgik Aug 22 '14 at 10:33
  • 1
    This should be marked as the correct answer by OP. My other entities does not have @GeneratedValue annotation but they work, only had to add this to one entity. weird. but anyways, Thank you! – Jero Dungog Nov 14 '18 at 10:38
  • Thanks for the answer. Also, it doesn't have to be `Long` in java, it can be `Integer` – Jonathan Lee Dec 22 '20 at 08:12
  • How do you handle cases of inheritance? I have defined a POJO that gets inherited by an entity and projection. The id is defined in the POJO – TheRealChx101 Sep 18 '21 at 13:03
  • 1
    @TheRealChx101 annotate the POJO with `@MappedSuperclass` (but don’t annotate with `@Entity`). and annotate its `id` column with `@Id`. – Bohemian Sep 18 '21 at 20:25
13

Resolved this problem using a Sequence ID defined in Oracle database.

ORACLE_DB_SEQ_ID is defined as a sequence for the table. Also look at the console to see the Hibernate SQL that is used to verify.

@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;
user2601995
  • 6,463
  • 8
  • 37
  • 41
  • For me , `unique = true, nullable = false` was necessary since DB schema was like that. Just specifying `@Id` & `@GeneratedValue` didn't work for me. Thanks. – Sabir Khan Jul 10 '19 at 11:56
5

Here is what I did to solve just by 2 ways:

  1. make ID column as int type

  2. if you are using autogenerate in ID dont assing value in the setter of ID. If your mapping the some then sometimes autogenetated ID is not concedered. (I dont know why)

  3. try using @GeneratedValue(strategy=GenerationType.SEQUENCE) if possible

Carsten
  • 11,287
  • 7
  • 39
  • 62
jaskirat Singh
  • 696
  • 1
  • 8
  • 17
4

For hibernate it is important to know that your object WILL have an id, when you want to persist/save it. Thus, make sure that

    private String U_id;

will have a value, by the time you are going to persist your object. You can do that with the @GeneratedValue annotation or by assigning a value manually.

In the case you need or want to assign your id's manually (and that's what the above error is actually about), I would prefer passing the values for the fields to your constructor, at least for U_id, e.g.

  public Role (String U_id) { ... }

This ensures that your object has an id, by the time you have instantiated it. I don't know what your use case is and how your application behaves in concurrency, however, in some cases this is not recommended. You need to ensure that your id is unique.

Further note: Hibernate will still require a default constructor, as stated in the hibernate documentation. In order to prevent you (and maybe other programmers if you're designing an api) of instantiations of Role using the default constructor, just declare it as private.

matthaeus
  • 797
  • 2
  • 7
  • 17
1

if you want to give id's value manually like JSON or other way you can add @JsonProperty(" U_id") notation before your U_id variable

Eklas_Rh
  • 11
  • 1
1

I got same error for different scenario. In my case my primary key of table is a VARCHAR value, so in the entity class(Entity1) ID is a String value, can't set it to auto generate. Also this entity join with another entity(Entity2).

When I set value of Entity1 to empty in updating Entity2 and calling save(), it's throw this exception. There setting empty string for id not work.

Entity2 e2 = new Entity2();

Entity1 e1 = new Entity1();
e1.setId("");
e2.setEntity1(e1);

session.update(e2);

Also setting null for id not work.

Entity2 e2 = new Entity2();

Entity1 e1 = new Entity1();
e1.setId(null);
e2.setEntity1(e1);

session.update(e2);

This way it's work.

Entity2 e2 = new Entity2();
e2.setEntity1(null);
session.update(e2);
0

Got this error with H2 database when mismatched type for numerical id value. Generated and populated table via number of sql statements and set id to be INT. Later created Entity Java class and set id to be Long. Issue was resolved after adjusting type of id in Java class.

metatron
  • 551
  • 6
  • 7
0

FROM UI you have to pass the ID (primary Key) Then observer you are saving or updating if you are saving use save method or use saveOrUpdate method

0

change class field value in your entity.hbm.xml to identity or sequense like

<hibernate-mapping>
<class name="models.Manager" table="Managers">
    <id name="id">
        <generator class="identity"></generator>
    </id>
    <property name="name"></property>
    <property name="surname"></property>
    <property name="department"></property>
    <property name="project_id"></property>
</class>

and add if you still dont have these code for your entity id:

@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)

that worked for me

kloud
  • 11
  • 1
0

I got this problem because I had 2 Id's annotations inside my entity class, one above my id field and one above my getter method

so make sure that there is only one Id annotation above your id field

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 11 '22 at 07:00