Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConstraintViolationException: NOT NULL when using Spring, HSQL and Hibernate

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

like image 273
Mathias G. Avatar asked May 20 '14 13:05

Mathias G.


1 Answers

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.

like image 187
j.con Avatar answered Oct 19 '22 17:10

j.con