Hi Folks!
I have a many-to-many association of two tables 'employee' and 'department' joined by the table 'empdept' which has one additional field "position" as you can see below. When I try to insert a new employee with his department, I get only the 'employee' table filled. And the following error: null value in column "position" violates not-null constraint. Without the additional field "position", everything works!
Can someone please tell me how to do it right? The forum contributions weren't very helpfull.
Thank you for any help!
alioum
Hibernate version:2.1
Employee
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class
name="org.alioum.test.Employee"
table="employee"
>
<meta attribute="class-description" inherit="false">
@hibernate.class
table="employee"
</meta>
<id
name="employeeId"
type="java.lang.Integer"
column="employee_id"
unsaved-value="any"
>
<meta attribute="field-description">
@hibernate.id
generator-class="assigned"
type="java.lang.Integer"
column="employee_id"
</meta>
<generator class="assigned" />
</id>
<property
name="salary"
type="int"
column="salary"
not-null="true"
length="4"
>
<meta attribute="field-description">
@hibernate.property
column="salary"
length="4"
not-null="true"
</meta>
</property>
<!-- associations -->
<!-- bi-directional many-to-many association to Role -->
<set
name="roles"
lazy="true"
inverse="true"
table="emprole"
cascade="all"
>
<meta attribute="field-description">
@hibernate.set
lazy="true"
inverse="true"
table="emprole"
cascade="all"
@hibernate.collection-key
column="employee_id"
@hibernate.collection-many-to-many
class="org.alioum.test.Role"
</meta>
<key>
<column name="employee_id" />
</key>
<many-to-many
column="role_id"
class="org.alioum.test.Role"
/>
</set>
<!-- bi-directional many-to-many association to Department -->
<set
name="departments"
lazy="true"
inverse="true"
table="empdept"
cascade="none"
>
<meta attribute="field-description">
@hibernate.set
lazy="true"
inverse="true"
table="empdept"
cascade="all"
@hibernate.collection-key
column="employee_id"
@hibernate.collection-many-to-many
class="org.alioum.test.Department"
</meta>
<key>
<column name="employee_id" />
</key>
<many-to-many
column="department_id"
class="org.alioum.test.Department"
/>
</set>
</class>
</hibernate-mapping>
Department
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class
name="org.alioum.test.Department"
table="department"
>
<meta attribute="class-description" inherit="false">
@hibernate.class
table="department"
</meta>
<id
name="departmentId"
type="java.lang.Integer"
column="department_id"
unsaved-value="any"
>
<meta attribute="field-description">
@hibernate.id
generator-class="assigned"
type="java.lang.Integer"
column="department_id"
</meta>
<generator class="assigned" />
</id>
<property
name="name"
type="java.lang.String"
column="name"
not-null="true"
length="50"
>
<meta attribute="field-description">
@hibernate.property
column="name"
length="50"
not-null="true"
</meta>
</property>
<property
name="description"
type="java.lang.String"
column="description"
length="255"
>
<meta attribute="field-description">
@hibernate.property
column="description"
length="255"
</meta>
</property>
<!-- associations -->
<!-- bi-directional many-to-many association to Employee -->
<set
name="employees"
lazy="true"
table="empdept"
cascade="none"
>
<meta attribute="field-description">
@hibernate.set
lazy="true"
table="empdept"
@hibernate.collection-key
column="department_id"
@hibernate.collection-many-to-many
class="org.alioum.test.Employee"
</meta>
<key>
<column name="department_id" />
</key>
<many-to-many
column="employee_id"
class="org.alioum.test.Employee"
/>
</set>
</class>
</hibernate-mapping>
Association table empdept
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class
name="org.alioum.test.Empdept"
table="empdept"
>
<meta attribute="class-description" inherit="false">
@hibernate.class
table="empdept"
</meta>
<composite-id>
<meta attribute="class-description" inherit="false">
@hibernate.id
generator-class="assigned"
</meta>
<!-- bi-directional many-to-one association to Employee -->
<key-many-to-one
name="employee"
class="org.alioum.test.Employee"
>
<meta attribute="field-description">
@hibernate.many-to-one
column="employee_id""
</meta>
<column name="employee_id" />
</key-many-to-one>
<!-- bi-directional many-to-one association to Department -->
<key-many-to-one
name="department"
class="org.alioum.test.Department"
>
<meta attribute="field-description">
@hibernate.many-to-one
column="department_id""
</meta>
<column name="department_id" />
</key-many-to-one>
</composite-id>
<property
name="position"
type="int"
column="position"
not-null="true"
length="4"
>
<meta attribute="field-description">
@hibernate.property
column="position"
length="4"
not-null="true"
</meta>
</property>
<!-- associations -->
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
Transaction tx = session.beginTransaction();
//create an employee
log.info("Create an Employee");
Employee employee = new Employee();
employee.setEmployeeId(new Integer(random.nextInt(10000)));
employee.setSalary(4600);
//create a Department
log.info("Create a Department");
Department department = new Department();
department.setDepartmentId(new Integer(random.nextInt(10000)));
department.setName("TEST_DEPARTMENT");
department.setDescription("It is just the test dpt, not a real one!!");
//link the department to the employee
log.info("link the department to the employee");
employee.setDepartments(new HashSet());
employee.getDepartments().add(department);
//link the employee to the department
log.info("link the employee to the department");
department.setEmployees(new HashSet());
department.getEmployees().add(employee);
//instantiate and populate the association class
Empdept empdept = new Empdept(1,employee,department);
//empdept.setEmployee(employee);
//empdept.setDepartment(department);
//empdept.setPosition(1);
//now we need to save the objects to the database
session.save(employee);
session.save(department);
session.save(empdept);
//JUnit stuff;
assertEquals(employee.getSalary(), 4600);
assertEquals(department.getName(), "TEST_DEPARTMENT");
session.flush();
tx.commit();
Full stack trace of any exception that occurs:
11:36:59,737 ERROR JDBCExceptionReporter:46 - ERROR: null value in column "position" violates not-null constraint
11:36:59,737 DEBUG BatcherImpl:199 - done closing: 0 open PreparedStatements, 0 open ResultSets
11:36:59,737 DEBUG BatcherImpl:240 - closing statement
11:36:59,752 DEBUG JDBCExceptionReporter:36 - SQL Exception
Batch-Anweisung Nummer 0 (insert into res.empdept (department_id, employee_id) values () wurde abgebrochen.
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:107)
at net.sf.hibernate.impl.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:54)
at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:118)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2311)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2265)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2187)
at org.alioum.Many2ManyInsertTest.testInsertEmpDept(Many2ManyInsertTest.java:130)
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:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)
Name and version of the database you are using:
Postgresql 7.4beta4
The generated SQL (show_sql=true):
Hibernate: insert into res.department (name, description, department_id) values (?, ?, ?)
Hibernate: insert into res.empdept (position, employee_id, department_id) values (?, ?, ?)
Debug level Hibernate log excerpt: DEBUG