Issue
This is my Database structure, One-to-One mapping in MySQL:
This is my java file:
public class Employee {
private EmployeeDetail empdetail;
private String firstname;
private String lastname;
// getters and setters
}
public class EmployeeDetail {
private Employee employee ;
private int employee_id;
private String street;
private String city;
private String state;
private String country;
// getters and setters
}
This is my mapping file:
<hibernate-mapping>
<class name="Employee" table="employee">
<id name="employee_id" type="java.lang.Integer" column="employee_id">
<generator class="assigned" />
</id>
<one-to-one name="empdetail" class="EmployeeDetail"
cascade="all"></one-to-one>
<property name="firstname" type="java.lang.String" column="firstname" />
<property name="lastname" type="java.lang.String" column="lastname" />
</class>
<class name="EmployeeDetail" table="employeedetail">
<id name="employee_id" type="java.lang.Integer" column="employee_id">
<generator class="foreign">
<param name="property">employee</param>
</generator>
</id>
<one-to-one name="employee" class="Employee"
cascade="save-update"></one-to-one>
<property name="street" type="java.lang.String" column="street" />
<property name="city" type="java.lang.String" column="city" />
<property name="state" type="java.lang.String" column="state" />
<property name="country" type="java.lang.String" column="country" />
</class>
</hibernate-mapping>
This is my client program:
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
EmployeeDetail edetail = new EmployeeDetail();
edetail.setCity("Hyd");
edetail.setCountry("India");
edetail.setEmployee_id(222);
edetail.setState("Andhra Pradesh");
Employee employee = new Employee();
employee.setEmployee_id(222);
employee.setFirstname("Pavan");
employee.setLastname("Jaooi");
employee.setEmpdetail(edetail);
session.merge(employee);
tx.commit();
session.close();
factory.close();
This is the exception I am getting:
INFO: Not binding factory to JNDI, no JNDI name configured
Hibernate: select employee0_.employee_id as employee1_0_1_, employee0_.firstname as firstname0_1_, employee0_.lastname as lastname0_1_, employeede1_.employee_id as employee1_1_0_, employeede1_.street as street1_0_, employeede1_.city as city1_0_, employeede1_.state as state1_0_, employeede1_.country as country1_0_ from employee employee0_ left outer join employeedetail employeede1_ on employee0_.employee_id=employeede1_.employee_id where employee0_.employee_id=?
Hibernate: select employeede0_.employee_id as employee1_1_0_, employeede0_.street as street1_0_, employeede0_.city as city1_0_, employeede0_.state as state1_0_, employeede0_.country as country1_0_ from employeedetail employeede0_ where employeede0_.employee_id=?
Exception in thread "main" org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: employee
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:44)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:99)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:186)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:240)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:120)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:456)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:194)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:240)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:120)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
at CustomerClient.main(CustomerClient.java:31)
Solution
You told Hibernate to generate the EmployeeDetail ID from the ID of its employee
property, but you never initialized this property.
Add edetail.setEmployee(employee);
to your code.
Answered By - JB Nizet
Answer Checked By - Candace Johnson (JavaFixing Volunteer)