0

我有三张桌子:

Company
id  name
1   Fred Co.

Person
id   name
1    Fred

Employee
id company_id person_id rank
1  1          1         1
2  1          1         2

现在排名被不同的应用程序使用,但对于我正在使用的内容,我并不关心它。我想做的是创建一个只返回唯一员工的休眠映射(通过域模型)。

我目前有

class Person {
    @Column(name = "id")
    Long id;

    @Column(name = "name")
    String id;
}

class Company {
    @Column(name = "id")
    Long id;

    @Column(name = "name")
    String id;

    @ManyToMany(fetch = FetchType.LAZY)
        @JoinTable(name = "EMPLOYEE", 
                joinColumns = { @JoinColumn(name = "COMPANY_ID") },
                inverseJoinColumns = { @JoinColumn(name = "PERSON_ID") })
    @LazyCollection(LazyCollectionOption.EXTRA)
    List<Person> employees = new ArrayList<Person>();
}

但这意味着fredCo.employees.size() == 2。如何过滤以便只返回唯一的人?

我想通过域模型来做到这一点。

编辑:虽然上面的例子很小,但在现实生活中,Person 对象非常大,每个公司有 1000 名员工(因此非常懒惰)。

现在我可以(并且已经)得到一个

companyDao.getEmployeesFor(Company...)
companyDao.getEmployeeCountFor(Company...)

但感觉有点恶心,我想在没有 Dao 的情况下这样做。

4

1 回答 1

2

如果排名始终设置并且第一条记录始终为“1”,那么您可以在映射中添加一个简单的@Where/@WhereJoinTable 子句,将集合限制为排名为 1 的记录。

https://access.redhat.com/knowledge/docs/en-US/JBoss_Enterprise_Application_Platform/5/html/Hibernate_Annotations_Reference_Guide/entity-hibspec-collection.html

另一种方法是将集合更改为 Set 并在不涉及“rank”字段的 Person 上实现 equals() 方法。

更新:

好的,正如您之前所说,这将不起作用。我已经进行了一些测试,而且似乎当在关联上定义 @LazyCollection 时,无论如何都会忽略对该关联的 @Where 限制。在超惰性集合上调用 size() 实际上会导致 Hibernate 对数据库发出 count() 查询。没有附加附加条款。

为什么应该忽略@Where 我不知道,但这已在其他地方查询过,似乎是一个悬而未决的问题:

https://forum.hibernate.org/viewtopic.php?f=9&t=988631&view=previous

https://hibernate.onjira.com/browse/HHH-3319

我认为您仍然可以通过创建一个附加的 Employee 实体来做您想做的事情,该实体映射到使用之前的 SQL 内部查询定义的 VIEW - 然后在数据库级别完成过滤。将实体映射到视图与表一样。

然后用两个从公司和个人到员工的一对多关联替换您的多对多。

于 2012-07-16T13:29:57.187 回答