2010-08-26 71 views
2

我不是100%确定这只是一个Hibernate问题,因为这可能是一个更抽象的决定,但我会试一试。
由于问题描述有点冗长,我将首先声明我想要做的是看看我是否可以将实现更改为更类似于最佳实践的实现。如何实现与Hibernate的3多对多关系?

我有3个与此问题相关的实体:工作站(ws),员工和组织单位(组织单位)。
员工可以属于一个组织单位。
一个组织单位可以容纳很多员工。
工作站用于显示组织单位(一般情况下),组织单位和特定员工以及不属于组织单位的员工的数据。

目前,由于各种原因,不受我控制,我们不使用Hibernate中的实体或通过DB约束之间的任何关联,但我们只是使用逻辑上充当外键的列。
我们目前有一个额外的表,其中有4列:Id,WSId,EmployeeId,OrgUnitId。
这允许WS引用一个orgunit(其中employeeId为null),一个没有组织单位(orgunitId为空)的雇员或者一个雇员和org-unit(其中都不为空)。

我希望能够知道:
1.Given一个WS,哪些员工是它下面和组织单位,以及如何(即独自一人,与员工哪个?)
2。给定一名员工,WS正在监控它。
3.给定一个组织单位,哪个WS正在监视它以及如何(即,单独与员工?哪个?)
这个问题与表示层有关,因为它决定了视图会被生成但是它是一个部分域模型作为用户将使用一个接口来操作这些监视映射,因此这些映射是域模型的一部分。

我不确定我所拥有的东西在选项中并不是最不可避免的,我会非常感谢意见和建议。

EDIT从其中一个答案中,我认为WS并不能清楚地显示出许多这样的映射的数据同时在上述类型(组织,雇员等)

回答

1

好的,我不知道如何在数据库端实现这一点,但这里是一个实体模型,应该涵盖你正在谈论的关系。

编辑: 这是针对您的意见的新版本。现在每个WorkStation都有n个绑定,每个绑定可以有员工或者orgunit或者两者都有(使用数据库约束来确保他们都没有)。

您也可以访问绑定每单位部门和每个员工,这将使上述查询更加容易:

@Entity 
public class OrgUnit{ 

    @OneToMany(mappedBy="orgUnit") 
    private Set<Binding> bindings; 

} 

@Entity 
public class Employee{ 

    @OneToMany(mappedBy="employee") 
    private Set<Binding> bindings; 

} 

@Entity 
public class Binding{ 

    @ManyToOne(optional = true) 
    private Employee employee; 

    @ManyToOne(optional=true) 
    private OrgUnit orgUnit; 

    @ManyToOne(optional=false) 
    private WorkStation owner; 

} 

@Entity 
public class WorkStation{ 

    @OneToMany(mappedBy="owner") 
    private Set<Binding> bindings; 

} 

示例客户端代码:

public Set<WorkStation> getWorkstationsPerEmployee(final Employee employee){ 
    final Set<WorkStation> workStations = new HashSet<WorkStation>(); 
    for(final Binding binding : employee.getBindings()){ 
     WorkStation workStation = binding.getOwner(); 
     if(workStation!=null) 
      workStations.add(workStation); 
    } 
    return workStations; 
} 
+0

感谢您的回复。我不确定在组织/员工中,WS的@OneToOne映射作为单个组织单位/员工的@OneToOne映射可以被许多WS同时监控。 另外,你的'WorkstationEmployeeBinding'是我想到的,但是如果你从注释的开头添加我的输入,你会看到我还需要'WorkstationOrgUnitBinding'和'OrgUnitEmployeeBinding'来反映所有的多对多。所有这些额外的虚拟类别都不觉得是正确的方向,但我可能会误解。谢谢。 – Ittai 2010-08-26 13:13:59

+0

@Ittai现在,这里有一个更简单但更灵活的解决方案,只有一个绑定类 – 2010-08-26 13:46:47

+0

感谢您的解决方案。我希望有一个“内部”的休眠解决方案,但我想这是必须要做的。再次感谢 – Ittai 2010-08-28 15:32:40

0

听起来像所有你真正需要的是Employee对OrgUnit的一个可空FK,以及对Employee和OrgUnit的WS的两个可空FK。要查看哪些WS正在监视员工,只需使用与emp_id列匹配的所有WS。与WS监视OrgUnit一样,可能会附加规定emp_id为空或不是(取决于您是否需要单独处理这些情况)。不知道“病人”的位置,你没有提供任何细节。

+0

很抱歉的“病人”,我当我添加该行时,它分心了,它应该是员工。我已经纠正了这个问题。我还添加了一个更新,我认为您错过了一个问题,因为您的解决方案忽略了WS可以监视许多此类映射的事实。谢谢。 – Ittai 2010-08-26 13:10:02

+0

在这种情况下,您可能已经有适当的解决方案。可能的更改是删除虚假的“id”字段,并且只有三部分主键(恰好是整个记录),或者将该表拆分为单独的WS-> Emp和WS-> OrgUnit映射,但我不知道这些都是真正的改进(除非关联表将会非常大,在这种情况下,如果将它分开,它可能会使管理更容易)。 – TMN 2010-08-26 13:25:47

+0

哎呀,忘了这是在休眠,所以你会想保留人工ID。 – TMN 2010-08-26 13:27:15

相关问题