1

There is a structure. I want to link the three entities in this way: the Company should contain id, name of company and the list of Departments, each Department has a list of Workers, id and name of department. Each worker has name, id.

+Company
-int companyId
-String companyName
-Set<Department> listOfDepartments = new HashSet<Department>();

+Department
-int departmentId
-String departmentName
-Set<Worker> listOfWorkers = new HashSet<Worker>();

+Worker
-int workerId
-String workerName

I tried to make a connection with the one-to-many and many-to-one, but is not successful.

Сompany

@Entity
@Table(name="Company")
public class Company {

@Id @GeneratedValue(strategy = GenerationType.AUTO)
private int idCompany;
private String companyName;

@OneToMany(mappedBy = "company")
private Set<Department> listOfDepartments = new HashSet<Department>();

Department

@Entity
public class Department {

@Id @GeneratedValue(strategy = GenerationType.AUTO)
private int idDepartment;
private String departmentName;

@ManyToOne
@JoinColumn(name="idCompany")
private Company company;

@OneToMany(mappedBy = "department")
private Set<Worker> listOfWorkers = new HashSet<Worker>();

Worker

@Entity
public class Worker {

@Id @GeneratedValue(strategy = GenerationType.AUTO)
private int idWorker;
private String workerName;

@ManyToOne
@JoinColumn(name="idDepartment")

I start with:

Session session = sessionFactory.openSession();
        session.beginTransaction();
        Worker worker1 = new Worker("WorkerName1");
        Worker worker2 = new Worker("WorkerName2");
        Worker worker3 = new Worker("WorkerName3");
        Worker worker4 = new Worker("WorkerName4");
        Department department = new Department("Technical");
        department.getListOfWorkers().add(worker1);
        department.getListOfWorkers().add(worker2);
        department.getListOfWorkers().add(worker3);
        department.getListOfWorkers().add(worker4);
        company = new Company("MyCompanyName");
        company.getListOfDepartments().add(department);
        session.save(company);
        session.getTransaction().commit();
        session.close();

It fills company, but not fills other tables and also it's not creating any joins(maps) Error:

Hibernate: alter table Department drop foreign key FK_l7sg67atqhnn0soqynpvxrtpk
Hibernate: alter table Worker drop foreign key FK_s53hyohtyjy93srd2wkksairk
Hibernate: drop table if exists Company
Hibernate: drop table if exists Department
Hibernate: drop table if exists Worker
Hibernate: create table Company (idCompany integer not null auto_increment, companyName varchar(255), primary key (idCompany))
Hibernate: create table Department (idDepartment integer not null auto_increment, departmentName varchar(255), idCompany integer, primary key (idDepartment))
Hibernate: create table Worker (idWorker integer not null auto_increment, workerName varchar(255), idDepartment integer, primary key (idWorker))
Hibernate: alter table Department add index FK_l7sg67atqhnn0soqynpvxrtpk (idCompany), add constraint FK_l7sg67atqhnn0soqynpvxrtpk foreign key (idCompany) references Company (idCompany)
Hibernate: alter table Worker add index FK_s53hyohtyjy93srd2wkksairk (idDepartment), add constraint FK_s53hyohtyjy93srd2wkksairk foreign key (idDepartment) references Department (idDepartment)
ноя 11, 2013 3:10:31 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: insert into Company (companyName) values (?)
DataNucleus
  • 15,497
  • 3
  • 32
  • 37
Eldar
  • 153
  • 5
  • 13

3 Answers3

10

In addition to the cascade mentioned in Glenn Lane's answer, you also need to understand how bidirectional associations work.

They have an owner side, and an inverse side. JPA only cares about the owner side to decide which association exists between entities. The owner side is the one which doesn't have the mappedBy attribute.

Your code add depertments to the company, and workers to the departments, but it only initializes the inverse sides. You forgot to initialize the owner side:

worker1.setDepartment(department);
worker2.setDepartment(department);
...
department.setCompany(company);
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
2

If you want JPA to automatically persist the children, you need to further decorate your @OneToMany:

@OneToMany(mappedBy = "department", cascade={CascadeType.PERSIST})

If you want cascading behaviour for other operations, like remove, merge, refresh, you'll need to add those to the cascade list as well.

Glenn Lane
  • 3,892
  • 17
  • 31
  • The result the same : `Hibernate: insert into Company (companyName) values (?)` I mean nothing in department and workers. – Eldar Nov 10 '13 at 22:43
  • You need to add the cascade to all your @OneToMany annotations, including the one in Company – Glenn Lane Nov 10 '13 at 22:45
0

You can use another approach:

Unidirectional OneToMany: http://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Unidirectional_OneToMany.2C_No_Inverse_ManyToOne.2C_No_Join_Table_.28JPA_2.0_ONLY.29

You still need to persist the Object and then add it into your Collection.

r1ckr
  • 5,643
  • 5
  • 20
  • 24