ConstraintViolationException: NOT NULL when using Spring, HSQL and Hibernate

11,051

Remove the nullable = false on the line @JoinColumn(name = "INDIVIDUAL_ID", nullable = false, updatable = false, insertable = true). Because at the time hibernate is making the link ManyToOne the ID of individual is not yet established, thus causing your error. If you really want extra protection from null values then use @NotNull outside of the @JoinColumn. The nullable = false inside the @JoinColumn creates the constraint on the database, while @NotNull will keep it at the object layer.

Share:
11,051
Mathias G.
Author by

Mathias G.

Senior Java Developer/Architect

Updated on June 04, 2022

Comments

  • Mathias G.
    Mathias G. almost 2 years

    I get a NOT NULL constraint violation exception when trying to insert an object of type Individual in the DB. I use hsql version 2.3.2. I let hibernate generate the DB tables for me. In the normal code (where I use an SQLServer Database) everything works fine.

    This is my Individual Object, where the ID is generated by the database and is the primary key of the table.

    Individual object:

    @XmlRootElement
    @Entity
    @Table(name="INDIVIDUALS")
    public class Individual {
    
         @Id
         @GeneratedValue(strategy = GenerationType.IDENTITY)
         @Column(name="INDIVIDUAL_ID")
         private long id;
    

    In the HealthCareProfessional object, there is link towards the primary key of this Individual object:

    @Entity
    @Table(name="HEALTHCARE_PROFESSIONALS")
    public class HealthCareProfessional {
    
         @Id
         @GeneratedValue(strategy = GenerationType.IDENTITY)
         @Column(name="HEALTHCARE_PROFESSIONAL_ID")
         private long id;
    
         @ManyToOne
         @JoinColumn(name = "INDIVIDUAL_ID", nullable = false, updatable = false, insertable = true)
         private Individual individual;
    
         ...
    

    The application context where I define the entityManagerFactory looks like this:

     <jdbc:embedded-database id="dataSource" type="HSQL" />
    
     <bean id="emf"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="/persistence-unittest.xml" />
        <property name="persistenceUnitName" value="testingSetup"/>
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <!-- Create the database, please -->
                <property name="generateDdl" value="true" />
            </bean>
        </property>
     </bean>
    
     <bean id="jpaVendorAdaptor"
          class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    
     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="emf" />
     </bean>
    

    My persistence xml is defined as follows:

     <persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
    
        <persistence-unit name="testingSetup">
            <!-- The autodetection only works if the classes are packaged as a JAR. Doesn't work for unit tests. Go figure -->
            <class>be.healthconnect.pwg.domain.individual.HealthCareProfessional</class>
            <class>be.healthconnect.pwg.domain.individual.Individual</class>
    
            <properties>
                <property name="hibernate.archive.autodetection" value="" />
                <property name="hibernate.show_sql" value="true"/>
            </properties>
        </persistence-unit>
     </persistence>
    

    This is my unit test:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(value = {"classpath:/applicationContext-test.xml"})
    @Transactional
    public class IndividualDaoTest {
    
        private static final String SSIN_JELLE= "81062205558";
        private static final String NIHII = "123";
    
        @Autowired
        private IIndividualDao individualDao;
    
        @Before
        public void setUp() throws Exception {
            Individual individual = buildIndividual(SSIN_JELLE);
            individualDao.addIndividual(individual);
        }
    
        @Test
        public void testGetIndividualsBySSIN() throws Exception {
    
            final List<Individual> individuals = individualDao.getIndividuals(SSIN_JELLE);
            Assert.assertNotNull(individuals);
            Assert.assertEquals(1, individuals.size());
            Individual individual = individuals.get(0);
            Assert.assertNotNull(individual);
        }
    

    And this is the error message I got:

    javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: integrity constraint violation: NOT NULL check constraint; SYS_CT_10143 table: HEALTHCARE_PROFESSIONALS column: INDIVIDUAL_ID
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1360)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1288)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1294)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:860)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
    at com.sun.proxy.$Proxy34.persist(Unknown Source)
    at be.healthconnect.pwg.data_access.dao.impl.IndividualDao.addIndividual(IndividualDao.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
    at com.sun.proxy.$Proxy36.addIndividual(Unknown Source)
    at be.healthconnect.pwg.data_access.dao.impl.IndividualDaoTest.setUp(IndividualDaoTest.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
    

    I really don't understand why hsql doesn't use the generated values for the ID...