Reputation: 685
In my EclipseLink JPA system I want to access a custom query using a OneToMany. Unfortunately the database is not normalized.
Simplified my DB looks like this:
Company
ID Name
-----------
01 CompanyA
02 CompanyB
Person
ID Company_Id Name Occupation
------------------------------
01 01 Alice Management
02 01 Bob Accounting
03 01 Carl Accounting
The occupation is given as a natural key.
Very simplified I have the following code:
@Entity
class Company {
@Id
@Column private Integer id;
@Column private String name;
@OneToMany()
@JoinColumn(name="Company_Id")
private List<Person> persons;
}
@Entity
class Person {
@Id
@Column private Integer id;
@Column private Integer company_id;
@Column private String name;
@Column private String occupation;
}
So far it is running fine. Now I want to add a OneToMany relationship that that lists the occupations and gives me the possibility to get a list of persons that have that occupation.
I want to do:
for (Company c : myCollectionOfCompanyEntities) {
System.out.println(c.name);
for (OccupationsInCompany o : c.getOccupations()) {
System.out.println(o.name);
for (Person p : o.getPersons()) {
System.out.println(p.name);
}
}
}
How do I start to write that OccupationsInCompany class? If I simply create an entity class, JPA wants to read the data from a table.
I know how to get all the data by hand using custom queries. But is it possible to do this using OneToMany annotations?
Upvotes: 0
Views: 1059
Reputation: 21145
There are many ways to do this, but unless listing people by the occupation in a company is large part of the application, I don't know that it makes sense to add objects to your model that might affect any other use cases negatively - you will be forced to maintain this model when you may only want it sorted at one point in time.
Other options:
1) take your list of people and sort them by occupation in memory within the getOccupations method. This can then be stored in a transient occupation list so it doesn't need to be repeatedly done.
2)Query for it in one query. "Select c.name, p.occupation, p.name from company c join c.persons p order by c.name, p.occupation where..". This one query gives you everything without the need to traverse your object model. Depending on how often this is needed, you can add options to make either more efficient for your use cases.
Option 1 can be combined with JPA so that the organization list is populated upfront, such in a postLoad method. Any model changes will result in extra complexity and result in JPA doing the same work the model itself can handle just as well if not better.
Upvotes: 0
Reputation: 16041
You should be able to do this by using the @ElementCollection
annotation.
@ElementCollection
@CollectionTable(name = "PEOPLE", joinColumns = {@JoinColumn(name="Company_Id")})
private List<Person> people;
Useful link at WikiBooks.
Upvotes: 1