简体   繁体   English

未规范化的db中的JPA OneToMany关系

[英]JPA OneToMany relationship in a db that is not normalized

In my EclipseLink JPA system I want to access a custom query using a OneToMany. 在我的EclipseLink JPA系统中,我想使用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. 现在,我想添加一个OneToMany关系,该关系列出了职业,并让我有可能获得具有该职业的人的列表。

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? 我如何开始编写OccupationsInCompany类? If I simply create an entity class, JPA wants to read the data from a table. 如果仅创建一个实体类,那么JPA希望从表中读取数据。

I know how to get all the data by hand using custom queries. 我知道如何使用自定义查询手动获取所有数据。 But is it possible to do this using OneToMany annotations? 但是可以使用OneToMany注释来做到这一点吗?

You should be able to do this by using the @ElementCollection annotation. 您应该能够使用@ElementCollection批注来执行此操作。

@ElementCollection
@CollectionTable(name = "PEOPLE", joinColumns = {@JoinColumn(name="Company_Id")})
private List<Person> people;

Useful link at WikiBooks . WikiBooks上的有用链接。

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. 其他选项:1)获取人员列表,并在getOc​​cupations方法中按内存中的职业对他们进行排序。 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. 2)一次查询。 "Select c.name, p.occupation, p.name from company c join c.persons p order by c.name, p.occupation where..". “从公司c中选择c.name,p.occupation,p.name,按c.name,p.occupation where ..加入c.persons p订单。”。 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. 选项1可以与JPA结合使用,这样可以预先填充组织列表,例如采用postLoad方法。 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. 任何模型更改都会导致额外的复杂性,并使JPA进行模型本身可以处理的工作,即使不是更好也不能做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM