My DB Structure
STUDENT Table CREATE TABLE MY_OWNER.STUDENT ( STUDENT_ID VARCHAR2(50 BYTE), STUDENT_FIRSTNAME VARCHAR2(50 BYTE), STUDENT_LASTNAME VARCHAR2(50 BYTE) );
ALTER TABLE MY_OWNER.STUDENT ADD ( CONSTRAINT STUDENT_PK PRIMARY KEY (STUDENT_ID));
STUDENT_ID is primary-key
EXAM Table CREATE TABLE MY_OWNER.EXAM ( EXAM_NAME VARCHAR2(50 BYTE), STUDENT_ID VARCHAR2(50 BYTE), EXAMMARKS NUMBER ); ALTER TABLE MY_OWNER.EXAM ADD (CONSTRAINT EXAM_PK PRIMARY KEY (EXAM_NAME, STUDENT_ID)); ALTER TABLE MY_OWNER.EXAM ADD ( CONSTRAINT EXAM_R01 FOREIGN KEY (STUDENT_ID) REFERENCES MY_OWNER.STUDENT (STUDENT_ID));
STUDENT_ID & EXAM_NAME is composite primary-key STUDENT_ID is foreign key reference to STUDENT_ID in student table
-------------- Foreign key in Exam table is part composite primary key -- ------------ My Hibernate Mappings :
Student.hbm.xml <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.jagadeesh.hibernate.Student" table="STUDENT"> <id name="studentId" type="string"> <column name="STUDENT_ID" length="50" /> <generator class="uuid" /> </id> <property name="studentFirstname" type="string"> <column name="STUDENT_FIRSTNAME" length="50" /> </property> <property name="studentLastname" type="string"> <column name="STUDENT_LASTNAME" length="50" /> </property> <set name="exams" inverse="true" lazy="false" table="EXAM" fetch="select" cascade="all-delete-orphan"> <key> <column name="STUDENT_ID" length="50" not-null="true" /> </key> <one-to-many class="com.jagadeesh.hibernate.Exam" /> </set> </class> </hibernate-mapping>
Exam.hbm.xml <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.jagadeesh.hibernate.Exam" table="EXAM"> <composite-id name="id" class="com.jagadeesh.hibernate.ExamId"> <key-property name="examName" type="string"> <column name="EXAM_NAME" length="50" /> </key-property> <key-property name="studentId" type="string"> <column name="STUDENT_ID" length="50" /> </key-property> </composite-id> <many-to-one name="student" class="com.jagadeesh.hibernate.Student" update="false" insert="false" fetch="select"> <column name="STUDENT_ID" length="50" not-null="true" /> </many-to-one> <property name="exammarks" type="big_decimal"> <column name="EXAMMARKS" precision="22" scale="0" /> </property> </class> </hibernate-mapping>
-------- It is able to create record in Student table with out cascade.(I need to create record Exam table also)
With cascade,
A per my understanding(from my R&D , and hibernate logs) Hibernate Try to 1) Create record in Student 2) Create record in Exam 3) Update Foreign-Key(Student_id) in Exam
Because Foreign-Key is part of primary key it is failing with ConstraintViolationException
Please correct my hibernate mapping, such a way If I save Student with Exam data, It should create record in Both Student and Exam tables (with out using join table) ---------------------------------------
Error Log
ERROR - Could not synchronize database state with session org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:254) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1001) at com.wrightexpress.si.site.dao.SiteAdapterDao.save(SiteAdapterDao.java:390) at com.jagadeesh.unittest.TestDaoTest.testSave(TestDaoTest.java:112) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41) at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.junit.runners.ParentRunner.run(ParentRunner.java:220) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196) Caused by: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("WL_OWNER"."EXAM"."STUDENT_ID")
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343) at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10698) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:247) ... 31 more ERROR - HE-04 Error saving object: com.jagadeesh.hibernate.Student
----
|