Home > Net >  Hibernate doesn't auto increment id of entity { Country } ( using h2 data base )
Hibernate doesn't auto increment id of entity { Country } ( using h2 data base )

Time:01-08

I'm trying to insert some data into H2 database using HibernateTemplate but I don't know why hibernate doesn't auto increment id of entity { Country }. (the project contains all dependencies required for runing the application , spring dependencies , hibernate dependencies , ...)

error message:

Jan 07, 2022 9:46:43 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 5.6.3.Final
Jan 07, 2022 9:46:43 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
Jan 07, 2022 9:46:44 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
Hibernate: drop table if exists continent CASCADE 
Hibernate: drop table if exists country CASCADE 
Hibernate: create table continent (continent_id integer generated by default as identity, code varchar(40) not null, name varchar(40) not null, primary key (continent_id))
Hibernate: create table country (id integer generated by default as identity, code varchar(20) not null, devise varchar(20) not null, greetings varchar(20) not null, name varchar(40) not null, continent_id integer, primary key (id))
Hibernate: alter table continent add constraint UK_absgp10b2mechi5a14a52oej3 unique (code)
Hibernate: alter table continent add constraint UK_a3ha82cpgf40ee95robng6ml8 unique (name)
Hibernate: alter table country add constraint UK_5s4ptnuqtd24d4p9au2rv53qm unique (code)
Hibernate: alter table country add constraint UK_llidyp77h6xkeokpbmoy710d4 unique (name)
Hibernate: alter table country add constraint FKpymfsgrl32dy3gtl9r7rykkjg foreign key (continent_id) references continent
Jan 07, 2022 9:46:45 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
        -----------------------------------------------------------
        |   -Pour l'ajout d'un nouveau pays tapper            [1] |
        |   -Pour lister les informations d'un pays, tapper   [2] |
        |   -Pour supprimer un pays, tapper                   [3] |
        |   -Pour modifier des informations d'un pays, tapper [4] |
        |   -Pour lister tous les pays d'un continent, tapper [5] |
        |   -Pour sortir de l'application tapper              [0] |
        -----------------------------------------------------------
        =====>1
        Ajouter un nouveau pays (code,nom,devise,salutation): 
        uk,united_kingdom,GBP,Hello,EU
        Hibernate: select country0_.id as id1_1_, country0_.code as code2_1_, country0_.continent_id as continen6_1_, country0_.devise as devise3_1_, country0_.greetings as greeting4_1_, country0_.name as name5_1_ from country country0_ where country0_.code=?
        Hibernate: select continent0_.continent_id as continen1_0_, continent0_.code as code2_0_, continent0_.name as name3_0_ from continent continent0_ where continent0_.code=?
        Hibernate: insert into country (id, code, continent_id, devise, greetings, name) values (null, ?, ?, ?, ?, ?)
        Jan 07, 2022 9:46:50 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
        WARN: SQL Error: 23502, SQLState: 23502
        Jan 07, 2022 9:46:50 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
        ERROR: NULL not allowed for column "ID"; SQL statement:
        insert into country (id, code, continent_id, devise, greetings, name) values (null, ?, ?, ?, ?, ?) [23502-204]

Entity

    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    
    import lombok.Data;
    
    @Entity
    @Data
    @Table(name="country")
    public class Country {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
        @Column( unique = true, nullable = false, length = 40)
        private String name;
        @Column( unique = true, nullable = false, length = 20)
        private String code;
        @Column( unique = false, nullable = false, length = 20)
        private String devise;
        @Column( unique = false, nullable = false, length = 20)
        private String greetings;
        @ManyToOne(cascade = CascadeType.REFRESH , fetch = FetchType.EAGER)
        @JoinColumn(name = "continent_id")
        private Continent continent;
    }

Hibernate config

Hibernate configuration using annotaions

    import java.util.Properties;
    
    import javax.sql.DataSource;
    
    import org.apache.commons.dbcp2.BasicDataSource;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.orm.hibernate5.HibernateTemplate;
    import org.springframework.orm.hibernate5.HibernateTransactionManager;
    import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    @Configuration
    @EnableTransactionManagement
    public class HibernateConf {
    
        @Bean
        public LocalSessionFactoryBean sessionFactory() {
            LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
            sessionFactory.setDataSource(dataSource());
            sessionFactory.setPackagesToScan("app");
            sessionFactory.setHibernateProperties(hibernateProperties());
    
            return sessionFactory;
        }
    
        @Bean("dataSource")
        public DataSource dataSource() {
            BasicDataSource dataSource = new BasicDataSource();
            dataSource.setDriverClassName("org.h2.Driver");
            dataSource.setUrl("jdbc:h2:mem:db;");
    
            return dataSource;
        }
    
        @Bean
        public PlatformTransactionManager hibernateTransactionManager() {
            HibernateTransactionManager transactionManager = new HibernateTransactionManager();
            transactionManager.setSessionFactory(sessionFactory().getObject());
            [enter image description here][1]return transactionManager;
        }
    
        @Bean
        public HibernateTemplate getHibernateTemplate() {
            HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory().getObject());
            return hibernateTemplate;
        }
    
        private final Properties hibernateProperties() {
            Properties hibernateProperties = new Properties();
            hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
            hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
            hibernateProperties.setProperty("hibernate.show_sql", "true");
    
            return hibernateProperties;
        }
    }

DAO

DAO Layer. the exception throws whene I invoke addCountry method..

@Repository
    public class CountryDAOImpl implements CountryDAO {
        @Autowired
        private SessionFactory sessionFactory;
        @Autowired
        private HibernateTemplate hibernateTemplate;

        @Override
        public Country addCountry(Country country) {
            hibernateTemplate.save(country);
            System.out.println(country.toString());
            return country;
        }
    }

  

CodePudding user response:

This is a known issue of Hibernate ORM: HHH-14985, it generates invalid SQL for H2 that was accepted by H2 1.x and isn't accepted by default by H2 2.x. It was already fixed in sources of Hibernate ORM, so you need to wait for its next release before trying to use H2 2.0.

You can try to append ;MODE=LEGACY to JDBC URL of H2 as a temporary workaround, in this mode these invalid attempts to insert a NULL value into identity column with implicit NOT NULL constraint don't produce this error.

Unfortunately, you may run into some other incompatibility. In that case you need to downgrade to H2 1.4.200 (and remove that MODE setting).

  •  Tags:  
  • Related