Reputation: 25
I'm trying to build an application which will receive the XML file with list of Employees and store the parent-child/employee-manager relation in the single database table.
My XML file looks like this one:
<Employees>
<Employee manager="Patrick">Martin</Employee>
<Employee manager="Patrick">Kent</Employee>
<Employee manager="Martin">Mark</Employee>
<Employee>Hugo</Employee> <!-- root element of the employee-manager tree -->
<Employee manager="Hugo">Osa</Employee>
<Employee manager="Osa">Patrick</Employee>
</Employee>
One employee can have only one manager, but one manager can have multiple subordinates/employees.
I have no troubles when unmarshalling the received XML file but now I'm trying to create the appropriate model which will allow me to store the unmarshalled values in the database. Data should be stored in the table named "Employee" and should contain following data:
------------------------------
| id | Integer |
------------------------------
| employee_name | String |
------------------------------
| parent_id | Integer | -- reference to the manager
------------------------------
I created a new class named Employee
but I'm not sure how to define appropriate ManyToOne/OneToMany annotations.
Since I'm fairly new to this, I've Googled couple of examples and tutorials (as well as the answers on the similar questions here on Stack Overflow), but I guess I'm making some big mistake in this implementation when defining this model. My latest try looks like this:
public class Employee {
@Id
@GeneratedValue
private int id;
@Column(name = "parent_id")
@Transient
@ManyToOne(cascade={CascadeType.ALL})
private String managerName;
@Column(name = "employee_name")
@JoinColumn(name="parent_id")
private String employeeName;
// getters and setters
If anyone could point me in the the direction of defining appropriate model, it would be much, much appreciated!
Upvotes: 1
Views: 3999
Reputation: 24
You should simply have a ManyToOne relation to your Employee table, that is several employees can have the same manager (who is also an employee) and for the manager this field will remain empty, like this:
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id
@GeneratedValue
private int id;
@ManyToOne
private Employee manager;
@Column(name = "employee_name")
private String employeeName;
Upvotes: -1
Reputation: 32175
In Hibernate
when you want to map a ManyToOne
relationship you map it between entities and not just properties, so you need to reference an object of type Employee
and not only a String
or an id
.
Problems:
So your mapping is incorrect and will throw many mapping errors, instead of writing:
@Column(name = "parent_id")
@Transient
@ManyToOne(cascade={CascadeType.ALL})
private String managerName;
You need to map the ManyToOne
realtionship like this:
@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name="manager_id")
private Employee manager;
And make sure you map the other side of the relationship like this:
@OneToMany(mappedBy="manager")
private Set<Employee> subordinates = new HashSet<Employee>();
Also your mapping for the column employee_name
is incorrect, the
@JoinColumn
is only used for relationships and can't be used with a
simple column, you need to write it like this:
@Column(name = "employee_name")
private String employeeName;
The @Transient
is useless in your mapping, we only use it if we
want to use an attribute that won't be persisted in the database.
And most important make sure you map your class with @Entity
, so it can be
persisted in the database.
Example:
You can check Hibernate Self Join Annotations One To Many mapping example it uses the same model you want to implement.
Upvotes: 2