I am having problem with my Hibernate Mapping.
I have a many to one mapping between my entity.
The two tables in my Oracle DB are the following…
Employee
--------------------------
EMPLOYEE_ID
EMPLOYEE_FIRST_NAME
EMPLOYEE_LAST_NAME
HEALTH_PLAN_ID
Health_Plan
------------------=
HEALTH_PLAN_ID
HEALTH_PLAN_NAME
HEALTH_PLAN_RATE
And my mapping…
@Entity
@Table(name = "Employee")
@SequenceGenerator(name = "employee_seq", sequenceName = "employee_seq")
public class Employee {
private int employeeId;
private String firstName;
private String lastName;
private HealthPlan plan;
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "employee_seq")
@Column(name = "employee_id", nullable = false)
public int getEmployeeId() {
return employeeId;
}
@Column(name = "employee_first_name", nullable = false)
public String getFirstName() {
return firstName;
}
@Column(name = "employee_last_name", nullable = false)
public String getLastName() {
return lastName;
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "HEALTH_PLAN_ID")
public HealthPlan getPlan() {
return plan;
}
}
@Entity
@Table(name = "HEALTH_PLAN")
@SequenceGenerator(name = "HEALTH_PLAN_SEQ", sequenceName = "HEALTH_PLAN_SEQ")
public class HealthPlan {
private int healthPlanId;
private String healthPlanName;
private double healthPlanRate;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HEALTH_PLAN_SEQ")
@Column(nullable = false, name = "HEALTH_PLAN_ID")
public int getHealthPlanId() {
return healthPlanId;
}
@Column(nullable = false, name = "HEALTH_PLAN_NAME", unique = true)
public String getHealthPlanName() {
return healthPlanName;
}
@Column(nullable = false, name = "HEALTH_PLAN_RATE")
public double getHealthPlanRate() {
return healthPlanRate;
}
}
When I ran below code….
public static void main(String[] args) throws SQLException {
HealthPlanDaoImpl healthDao = new HealthPlanDaoImpl();
EmployeeDaoImpl empDao = new EmployeeDaoImpl();
HealthPlan plan = new HealthPlan();
plan.setHealthPlanName("PLAN B");
plan.setHealthPlanRate(5.0);
Employee emp = new Employee();
emp.setPlan(plan);
emp.setFirstName("Jane");
emp.setLastName("Doe");
boolean isSuccess = empDao.addEmployee(emp);
System.out.println(isSuccess);
}
public class EmployeeDaoImpl{
public boolean addEmployee(Employee emp) {
boolean bolReturn = true;
Session session = HibernateUtil.beginTransaction();
try {
session.save(emp);
HibernateUtil.commitTransaction();
} catch (Exception e) {
e.printStackTrace();
bolReturn = false;
HibernateUtil.rollbackTransaction();
}
return bolReturn;
}
}
In the Health_Plan Table, the HEALTH_PLAN_ID = 3 (Which is correct!!!)
In the Employee Table, the HEALTH_PLAN_ID = 1850 (Where did this value came from??? I expect this to be 3 also.)
I tried several times and I notice that in the Employee Table HEALTH_PLAN_ID just increment by 300.
I think I already set the cascade option.
Any hints?
creates a new
HealthPlaninstance for everyEmployeeinstance created. The originalHealthPlaninstance is not used in a new mapping between a newEmployeeand an existingHealthPlan. If you query for the existingHealthPlaninstance, and then set it to everyEmployee, you will find that the health plan id will be consistent across objects.The discrepancy in the values for the HEALTH_PLAN_ID values can be attributed to the afore mentioned behavior of your test code. Also, the sequence allocation size would have been incremented by 50, which is the default, and you happen to be seeing the result of six consecutive sequence increment operations. Note, that Hibernate will update sequences in a different transaction, so you will find that the sequence values will increment even if you rollback the current transaction.
On a different note, I would advise against using a unidirectional
@ManyToOnerelationship with aCascadeTypevalue of ALL. Do you really want to delete theHealthPlanof allEmployeeinstances if oneEmployeeis removed, or for that matter, allow updates ofHealthPlaninstances from an Employee to be propagated for merge events?