24

I'm starting with Hibernate and I have an error that I just can't figure out.

I have the following Classes:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractColumn {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private String id;
    private String name;

//Other stuff
}

Then I have

@Entity
public class DoubleColumn extends AbstractColumn  implements Column {

    @ElementCollection
    private Map<Double,String> isNA;
    private double min=0;
    private double max=0;
    @ElementCollection
    private List<Double> data;
    // a lot of stuff
}

And finally:

@Entity
public class DataFrame {
    @OneToMany(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private List<AbstractColumn> data;
    private String name;
    @Id
    @GeneratedValue
    private String id;
    @ElementCollection
    private Map<String,Integer> colIndex;
//more stuff
}

The error I'm getting is:

Exception in thread "main" org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String
    at org.hibernate.id.IdentifierGeneratorHelper.getIntegralDataTypeHolder(IdentifierGeneratorHelper.java:224)
    at org.hibernate.id.enhanced.SequenceStructure$1.getNextValue(SequenceStructure.java:98)
    at org.hibernate.id.enhanced.NoopOptimizer.generate(NoopOptimizer.java:40)
    at org.hibernate.id.enhanced.SequenceStyleGenerator.generate(SequenceStyleGenerator.java:432)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:105)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
    at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
    at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:675)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:667)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:662)
    at Main.main(Main.java:285)

The only hint that the error throws is that the error is in the main class here:

DoubleColumn c1 = new DoubleColumn("Datos varios");
        c1.addData(12);
        c1.addData(11);
        c1.addData(131);
        c1.addData(121);
        c1.addData(151);
        c1.addData(116);


        DataFrame datosHibernate = new DataFrame("Dataframe Hibernate");
        datosHibernate.addColumn(c1);


        Configuration hibernateConfig = new Configuration();
        SessionFactory sessionFactory = hibernateConfig.configure().buildSessionFactory();
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(datosHibernate);
        session.getTransaction().commit();
        session.disconnect();
        session.close();
        System.exit(0);

The ids are Strings, and I have them annotated as @GeneratedValue (I think I do not need to initialize them myself). The relation @OneToMany have the cascade annotation so it should be mapped correctly.

I've tried the code WITHOUT the session.save line and doesn't throw errors, so is not a problem in the code per se, it has to be something with Hibernate.

My configuration file is:

<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:h2:E:/bd;DB_CLOSE_DELAY=-1;MVCC=TRUE</property>
        <property name="connection.driver_class">org.h2.Driver</property>
        <property name="connection.username">user</property>
        <property name="connection.password"></property>
        <property name="dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">create</property>

        <mapping class="com.dataframe.estructuras.DataFrame"></mapping>
        <mapping class="com.dataframe.estructuras.column.AbstractColumn"/>
        <mapping class="com.dataframe.estructuras.column.types.DoubleColumn"/>
    </session-factory>
</hibernate-configuration>

It creates the database file and I see all the SQL code generated, tables and all. Is when it tries to store the info when the thing breaks.

5 Answers 5

56

If you want String to be database key you need to use UUID to automatically generate key. Something like this:

@Id @GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String myId;

UPDATE

The way of doing has evolved to the following usage

import org.hibernate.annotations.UuidGenerator;
// other code 
@Id
@UuidGenerator
public String id;
Sign up to request clarification or add additional context in comments.

5 Comments

And that solved the problem, but I have a new error if I can push my luck and paste it here... just in case :D
This is the new error: Error during managed flush [Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1] Thx for the help
Nevermind, solved. I was setting one of the ids in a different part. Everything seems to work. Thx again
Note that @GeneratedValue(generator="system-uuid") persists the generated UUID in the table, thereby the actual string value will not be saved. You should not use this if you want to save the String value in the table.
@GenericGenerator is a hibernate annotation. How to do the same only with javax.persistence annotations? I am thinking about being independent from the database driver implementation.
5

I was getting this error while using Postgres. I was using String for my Ids. Like this:

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private String id;

So I remove the @GeneratedValue annotation, as it doesn't go well with spring.

@Id

private String id;

Then it works!

Comments

2

I was facing the same issue and changing the strategy = GenerationType.UUID fixed the issue.

@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;

Comments

0

Dear you have used string for the id that why it is causing issue. make it to int or long and check the database field as well . In case some one else come looking for an answer .

@GenericGenerator(name = "generator", strategy = "increment")
    @Id
    @GeneratedValue(generator = "generator")
    @Column(unique=true, nullable=false, precision=10,name="paymentid")
    private  Long  

This will solve your problem

Comments

0

For future readers, especially those new to spring like myself, I had the same problem, even though my id was type Long.

Initially, I created the instance variables before annotating them, and then created the annotation at the to of all instance variables as shown below.

public class Student {
    @Id
    @SequenceGenerator(
            name = "student_sequence",
            sequenceName = "student_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            generator = "student_sequence",
            strategy = GenerationType.SEQUENCE
    )
    private String name;
    private Long id;
    private String email;

I only realised this problem after reading Aamir Khan's answer to this post, that in effect I was annotating the name(which is of type String) instead of the id, hence the error.

As can be seen from the solution below, putting id right below the annotations and just above the name solved the problem.

public class Student {
    @Id
    @SequenceGenerator(
            name = "student_sequence",
            sequenceName = "student_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            generator = "student_sequence",
            strategy = GenerationType.SEQUENCE
    )
    private Long id;
    private String name;
    private String email;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.