Sure, here you can find everything:
The Java Code for the POJO's:
Code:
package test.hibernate;
import java.util.*;
public class Company
{
private long id;
private String name;
private Set employees;
private Set customers;
public Company()
{
}
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Set getEmployees()
{
return employees;
}
public void setEmployees(Set employees)
{
this.employees = employees;
}
public void addEmployee(Employee employee)
{
employees.add(employee);
employee.setCompany(this);
}
public void removeEmployee(Employee employee)
{
employee.setCompany(null);
employees.remove(employee);
}
public Set getCustomers()
{
return customers;
}
public void setCustomers(Set customers)
{
this.customers = customers;
}
public void addCustomer(Customer customer)
{
customers.add(customer);
customer.getCompanies().add(this);
}
public void removeCustomer(Customer customer)
{
customers.remove(customer);
customer.getCompanies().remove(this);
}
}
Code:
package test.hibernate;
public class Employee
{
private long id;
private String firstName;
private String lastName;
private Address address;
private Company company;
public Employee()
{
}
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
public Address getAddress()
{
return address;
}
public void setAddress(Address address)
{
this.address = address;
}
public void addAddress(Address address)
{
this.address = address;
address.setEmployee(this);
}
public void removeAddress()
{
address.setEmployee(null);
address = null;
}
public Company getCompany()
{
return company;
}
public void setCompany(Company company)
{
this.company = company;
}
public void addCompany(Company company)
{
this.company = company;
company.getEmployees().add(this);
}
public void removeCompany()
{
company.getEmployees().remove(this);
company = null;
}
}
Code:
package test.hibernate;
public class Address
{
private long id;
private String street;
private Employee employee;
public Address()
{
}
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getStreet()
{
return street;
}
public void setStreet(String street)
{
this.street = street;
}
public Employee getEmployee()
{
return employee;
}
public void setEmployee(Employee employee)
{
this.employee = employee;
}
public void addEmployee(Employee employee)
{
this.employee = employee;
this.employee.setAddress(this);
}
public void removeEmployee()
{
employee.setAddress(null);
employee = null;
}
}
Code:
package test.hibernate;
import java.util.*;
public class Customer
{
private long id;
private String name;
private Set companies;
public Customer()
{
}
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Set getCompanies()
{
return companies;
}
public void setCompanies(Set companies)
{
this.companies = companies;
}
public void addCompany(Company company)
{
companies.add(company);
company.getCustomers().add(this);
}
public void removeCompany(Company company)
{
companies.remove(company);
company.getCustomers().remove(this);
}
}
The Hibernate Mapping Files:Code:
<hibernate-mapping>
<class name="test.hibernate.Company">
<id name="id"/>
<property name="name"/>
<set name="employees" inverse="true">
<key column="company"/>
<one-to-many class="test.hibernate.Employee"/>
</set>
<set name="customers" table="CompaniesCustomers" inverse="true">
<key column="companies"/>
<many-to-many column="customers" class="test.hibernate.Customer"/>
</set>
</class>
</hibernate-mapping>
Code:
<hibernate-mapping>
<class name="test.hibernate.Employee">
<id name="id"/>
<property name="firstName"/>
<property name="lastName"/>
<many-to-one name="address" column="address" unique="true" cascade="delete"/>
<many-to-one name="company" column="company"/>
</class>
</hibernate-mapping>
Code:
<hibernate-mapping>
<class name="test.hibernate.Address">
<id name="id"/>
<property name="street"/>
<one-to-one name="employee" property-ref="address"/>
</class>
</hibernate-mapping>
Code:
<hibernate-mapping>
<class name="test.hibernate.Customer">
<id name="id"/>
<property name="name"/>
<set name="companies" table="CompaniesCustomers">
<key column="customers"/>
<many-to-many column="companies" class="test.hibernate.Company"/>
</set>
</class>
</hibernate-mapping>
The Database Initialization Script:Code:
DROP TABLE IF EXISTS Company;
CREATE TABLE Company(
id BIGINT PRIMARY KEY,
name VARCHAR(30) NOT NULL
) TYPE=INNODB;
DROP TABLE IF EXISTS Employee;
CREATE TABLE Employee(
id BIGINT PRIMARY KEY,
firstName VARCHAR(30) NOT NULL,
lastName VARCHAR(30) NOT NULL,
address BIGINT UNIQUE,
company BIGINT
) TYPE=INNODB;
DROP TABLE IF EXISTS Address;
CREATE TABLE Address(
id BIGINT PRIMARY KEY,
street VARCHAR(30) NOT NULL
) TYPE=INNODB;
DROP TABLE IF EXISTS Customer;
CREATE TABLE Customer(
id BIGINT PRIMARY KEY,
name VARCHAR(30) NOT NULL
) TYPE=INNODB;
DROP TABLE IF EXISTS CompaniesCustomers;
CREATE TABLE CompaniesCustomers(
companies BIGINT,
customers BIGINT
) TYPE=INNODB;
One-to-one relationship:There is a one-to-one relationship between Employee and Address. The FK is the Employee table. The following code deletes an Address:
Code:
Session session = getHibernateSession();
Address address = (Address)session.get(Address.class.getName(), new Long(id));
session.delete(address);
After executing this code the Address row is deleted from the database but the FK is still in the Employee table. When getAddress is called on that Employee an Exception occurs since the Address doesn't exist anymore.
One-to-many relationship:There is a one-to-many relationship between Company and Employee. The FK is in the Employee table.The following code deletes a Company:
Code:
Session session = getHibernateSession();
Company company = (Company)session.get(Company.class.getName(), new Long(id));
session.delete(company);
When deleting the Company it is removed from the DB but the FK isn't set to null in the Employee table.
Many-to-many relationship:
There is a many-to-many relationship between Company and Customer with a seperate table CompaniesCustomers.
When a Customer is deleted Hibernate executes two SQL-statements, one to remove the Customer from the Customer table and one to clear it from the CompaniesCustomers table. This is great.
Unfortunately only one statement is executed when deleting a Company, the Company doesn't get removed from the CompaniesCustomers table.
I could solve these problems by removing the relationships in my code, before deleting an entity but i do have some problems with this:
1. It's overkill (but i could live with that).
2. When the entity gets deleted because of a cascade-delete (e.g. because of a delete of a parent) i can't call the code to clean-up its relationships.
I think this is all very basic stuff when working with relationships but what is the best way to handle it???