Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Doubt in Mapping Associations

 
Maneessh saxena
Ranch Hand
Posts: 125
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[size=18][size=12]hi Great Ranchers,

I’ve some doubt in Mapping Associations. Please refer the mapping and code below ….


<hibernate-mapping>
<class name="com.test.beans.Employee" table="employee">
<id name="empId" unsaved-value="0">
<generator class="increment" />
</id>

<many-to-one name="department" class="com.test.beans.Department"
cascade="all" column="employee_department">
</many-to-one>
<property name="name" />
</class>

<class name="com.test.beans.Department" table="department">

<id name="deptId" unsaved-value="0">
<generator class="increment" />
</id>

<property name="deptName"></property>
</class>

</hibernate-mapping>


Bean classes are as given below ……..


package com.test.beans;

public class Department {
private int deptId;

private String deptName;
……………………….Getter Setters.


And


package com.test.beans;

public class Employee {
private int empId;

private String name;

private Department department;
……………………….Getter Setters.

I tried the below code in main method to save an Employee object ….

Employee employee = new Employee();
employee.setName("Manish");
employee.setEmpId(1);

Department department = new Department();
department.setDeptName("BFSI");
department.setDeptId(1);

employee.setDepartment(department);

SessionFactory factory = new Configuration().configure()
.buildSessionFactory();

Session session = factory.openSession();

Transaction transaction = session.beginTransaction();

session.save(employee);

session.flush();

session.close();

transaction.commit();


I got the error given below …

Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`testhibernate/employee`, CONSTRAINT `FK4722E6AE8933862F` FOREIGN KEY (`employee_department`) REFERENCES `department` (`deptId`))
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1257)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:943)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:57)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:172)
... 6 more


……..


At the time I tried to insert Employee details in employee table the department table was empty.

1) My understanding is:-
As I could not have any record in employee table which’s not corresponding to department table and since department table is empty hence the error comes.



2) Now if I’ve to insert some employees in employee table I’ll have to follow the steps given below.

(i) I’ll have to create department object with deptId value i.e existing in the department table (assuming department table is populated with some objects).
(ii) Now creating employee object and pass department object created in above step to setDepartment() method.
(iii) Now call session.save(employee).

Is that the way to insert employees in the employee table ?

IS there any way, when I save employee object then it’s associated department object is automatically saved provided it’s not there department table previously?
[/size][/size]
 
Tomasz Szymanski
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
raunak saxena wrote:
IS there any way, when I save employee object then it’s associated department object is automatically saved provided it’s not there department table previously?

Yes, there is: cascading. And it should work in your example, because you've mapped the department with cascade="all" in your employee entity. Why isn't it working? I see one major thing that you're doing wrong: you're manually setting the identifier values in the employee and the department.
Since you've set up the generators for both of them, just let them do their job ;-) You should leave the identifiers at 0, because that's what you've declared as the unsaved-value.

But then... I bet it'll throw another exception, related to the order in which you're finishing the transaction. If it does, you'll probably figure out why.
 
Maneessh saxena
Ranch Hand
Posts: 125
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tomasz Szymanski wrote:

But then... I bet it'll throw another exception, related to the order in which you're finishing the transaction. If it does, you'll probably figure out why.



hi Tomasz,

Thanks for your reply. Yes it givies error if a corresponding record is not there in department/Parent table. And that's what my question is, Is there any way that when I save employee/child and corresponding record is not there in department/Parent table, both the records for parent & child tables could save automatically. Please let me know in case my question is not clear.


Thanks & Regards
 
Tomasz Szymanski
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your question is clear. Apparently my answer wasn't ;-)
So to cut it short, try doing two things:

1. remove the following lines from your code:

employee.setEmpId(1);
department.setDeptId(1);

2. at the end of your code, first commit, then close the session
 
Prabhat Jha
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The proper sequence is :

session.save(employee);
transaction.commit();
session.flush();
session.close();

If you call close before flush it will throw you error that session is already closed.
 
Tomasz Szymanski
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think flush() is actually needed. Commit should do it.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic