数据库中的JPA OneToMany关系未规范化

时间:2015-09-24 13:23:20

标签: java jpa eclipselink one-to-many

在我的EclipseLink JPA系统中,我想使用OneToMany访问自定义查询。不幸的是,数据库没有标准化。

Simplified my DB看起来像这样:

公司

ID Name      
-----------
01 CompanyA
02 CompanyB

ID Company_Id Name  Occupation
------------------------------
01 01         Alice Management
02 01         Bob   Accounting
03 01         Carl  Accounting

占领是一个自然的关键。

非常简化我有以下代码:

@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;
}

到目前为止,它运行良好。现在我想添加一个OneToMany关系,列出职业,并让我有可能获得有职业的人员名单。

我想这样做:

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);
        }
    }
}

如何开始编写 OccupationsInCompany 类?如果我只是创建一个实体类,JPA想要从表中读取数据。

我知道如何使用自定义查询手动获取所有数据。但是可以使用OneToMany注释来做到这一点吗?

2 个答案:

答案 0 :(得分:1)

您应该可以使用@ElementCollection注释来执行此操作。

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

WikiBooks的有用链接。

答案 1 :(得分:0)

有很多方法可以做到这一点,但除非按公司职业列出人员是应用程序的重要组成部分,否则我不知道在模型中添加可能影响任何其他用例的对象是有意义的否定 - 当你可能只希望它在一个时间点排序时,你将被迫维持这个模型。

其他选择: 1)获取您的人员列表,并在getOc​​cupations方法中按占用内存对其进行排序。然后可以将其存储在瞬态占用列表中,这样就不需要重复完成 2)在一个查询中查询它。 “选择c.name,p.occupation,p.name从公司c加入c.persons p order by c.name,p.occupation where ..”。这一个查询为您提供了所有内容,而无需遍历您的对象模型。根据需要的频率,您可以添加选项以使您的用例更有效。

选项1可以与JPA结合使用,以便预先填充组织列表,例如postLoad方法。任何模型更改都会导致额外的复杂性,并导致JPA做同样的工作,模型本身也可以处理,如果不是更好的话。