Перевести в спящий режим неизвестный интегральный тип данных для ids

#java #hibernate

#java #спящий режим

Вопрос:

Я начинаю с Hibernate, и у меня ошибка, которую я просто не могу понять.

У меня есть следующие классы:

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

//Other stuff
}
  

Тогда у меня есть

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

И, наконец:

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

Ошибка, которую я получаю, это:

 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)
  

Единственный намек на то, что возникает ошибка, заключается в том, что ошибка находится в основном классе здесь:

 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);
  

Идентификаторы представляют собой строки, и у меня они помечены как @GeneratedValue (я думаю, мне не нужно инициализировать их самостоятельно). Отношение @OneToMany имеет каскадную аннотацию, поэтому оно должно быть отображено правильно.

Я пробовал код БЕЗ строки session.save и не выдает ошибок, так что проблема не в коде как таковом, это должно быть что-то с Hibernate.

Мой файл конфигурации:

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

Он создает файл базы данных, и я вижу весь сгенерированный SQL-код, таблицы и все остальное. Это когда он пытается сохранить информацию, когда что-то ломается.

Ответ №1:

Если вы хотите, чтобы строка была ключом базы данных, вам нужно использовать UUID для автоматической генерации ключа. Что-то вроде этого:

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

Комментарии:

1. И это решило проблему, но у меня есть новая ошибка, если я смогу испытать свою удачу и вставить ее сюда… на всякий случай:D

2. Это новая ошибка: Ошибка во время управляемой очистки [Пакетное обновление вернуло неожиданное количество строк из обновления [0]; фактическое количество строк: 0; ожидаемое: 1] Спасибо за помощь

3. Неважно, решено. Я устанавливал один из идентификаторов в другой части. Кажется, все работает. Спасибо еще раз

4. Обратите внимание, что @GeneratedValue(generator=»system-uuid») сохраняет сгенерированный UUID в таблице, таким образом, фактическое строковое значение сохранено не будет. Вам не следует использовать это, если вы хотите сохранить строковое значение в таблице.

5. @GenericGenerator — это аннотация гибернации. Как сделать то же самое только с аннотациями javax.persistence? Я думаю о независимости от реализации драйвера базы данных.

Ответ №2:

Я получал эту ошибку при использовании Postgres. Я использовал String для своих идентификаторов. Вот так:

 @Id

@GeneratedValue(strategy = GenerationType.AUTO)

private String id;
  

Поэтому я удаляю аннотацию @GeneratedValue, поскольку она плохо сочетается с spring.

 @Id

private String id;
  

Тогда это работает!

Ответ №3:

Уважаемый, вы использовали string для идентификатора, поэтому это вызывает проблему. введите значение int или long и также проверьте поле базы данных . На случай, если кто-то еще придет в поисках ответа.

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

Это решит вашу проблему

Ответ №4:

Для будущих читателей, особенно для новичков в spring, таких как я, у меня была та же проблема, хотя мой идентификатор был type Long .

Первоначально я создал переменные экземпляра перед их аннотированием, а затем создал аннотацию в начале всех переменных экземпляра, как показано ниже.

 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;
  

Я понял эту проблему только после прочтения ответа Амира Кхана на этот пост, что фактически я комментировал имя (которое имеет тип String) вместо идентификатора, отсюда и ошибка.

Как видно из приведенного ниже решения, размещение идентификатора прямо под аннотациями и чуть выше имени решило проблему.

 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;