Java ConstraintViolationException: NOT NULL 使用 Spring、HSQL 和 Hibernate 时
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23760687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ConstraintViolationException: NOT NULL when using Spring, HSQL and Hibernate
提问by Mathias G.
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.
尝试在数据库中插入类型为 Individual 的对象时,出现 NOT NULL 约束冲突异常。我使用 hsql 版本 2.3.2。我让 hibernate 为我生成数据库表。在普通代码(我使用 SQLServer 数据库的地方)中,一切正常。
This is my Individual Object, where the ID is generated by the database and is the primary key of the table.
这是我的Individual Object,其中ID由数据库生成,是表的主键。
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:
在 HealthCareProfessional 对象中,有指向此 Individual 对象主键的链接:
@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:
我定义 entityManagerFactory 的应用程序上下文如下所示:
<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:
我的持久化 xml 定义如下:
<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.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.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access##代码##0(ParentRunner.java:53)
at org.junit.runners.ParentRunner.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...
我真的不明白为什么 hsql 不使用生成的 ID 值...
采纳答案by j.con
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.
去掉nullable = false
就行@JoinColumn(name = "INDIVIDUAL_ID", nullable = false, updatable = false, insertable = true)
。因为当时hibernate正在制作链接ManyToOne
,个人的ID尚未建立,从而导致您的错误。如果您真的想要对null
值进行额外保护@NotNull
,请在@JoinColumn
. 该nullable = false
内部@JoinColumn
创建数据库的约束,而@NotNull
将其保持在对象层。