我们有 2 个表(一个 Activity 表和一个存档表),它们具有相同的结构(例如 EmployeeEmployeeArchive )。为了能够利用公共(public)代码来使用两个表的结果,我们有一个抽象父类,它定义了所有方法和注释。
我们希望能够执行对两个表使用相同查询并将结果合并在一起的查询。

我们有另一个实体/表(例如 Organization )与 onetomanymanytoone/Employee 双向关系; Organization 有一个 ListEmployee s,每个员工都有一个组织。
当通过关联获取组织的员工时,我们只需要 Activity 表中的员工而不是文件。

有没有办法实现我们正在尝试的目标或可行的解决方法?

我们尝试了@MappedSuperclass@Entity/@InheritanceType.TABLE_PER_CLASS 的各种实现来尝试实现我们想要的。每个实现几乎都能实现我们想要的,但并不完全。例如,为了能够查询两个表,我们可以有一个带有 Entity 的抽象父 InheritanceType.TABLE_PER_CLASS ,但是我们不能在 mappedBy 中拥有与 EmployeeOrganization 关系。我们可以使用 MappedSuperclass 作为父级来建立正确的关系,但是我们无法通过联合查询 ArchiveActive 表。

这基本上是我们试图布局的内容:

    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class AbstractEmployee {
        @ManyToOne
        @JoinColumn(name="employeeId", nullable=false)
        Organization org;
        ...
    }

    @Entity
    public class Employee extends AbstractEmployee {
    }

    @Entity
    public class EmployeeArchive extends AbstractEmployee {
    }

    @Entity
    public class Organization {
       @OneToMany(cascade=ALL, mappedBy="org")
       List<Employee> employees;
       ...
    }

代码
    public List<AbstractEmployee> getAllEmployees()
    {
       Query query = em.createQuery("SELECT e FROM AbstractEmployee e where e.name = ‘John’", AbstractEmployee.class);
       return query.getResultList();
    }

    public List<Organization> getOrganizations()
    {
       Query query = em.createQuery("SELECT e FROM Organization o ", Organization.class);
       List<Organization> orgs = query.getResultList();
       // fetch or eager fetch the Employees but only get the ones from the active employee table
       return orgs;
    }

我们还尝试让父类扩展 MappedSuperclass 并将实现和注释放在 MappedSuperclass 中,但我们得到了 AnnotationExceptionOrganization 关系
    @MappedSuperclass
    public abstract class AbstractMapped {
        @ManyToOne
        @JoinColumn(name="employeeId", nullable=false)
        Organization org;
    }

    @Entity
    @Inheritance(@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS))
    public abstract class AbstractEmployee extends AbstractMapped {
        ... `Constructors` ...
    }

在部署时,我们得到以下异常:
    Caused by org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: Employee.org in Organizaztion.employees
       at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:685)

最佳答案

您可以通过更改 OrganizationEmployee 的映射来实现这一点,以便它使用关系表,而不是在 org 表中包含 Employee 字段。请参阅 Hibernate documentation 中的示例,对于您来说,它看起来像:

@Entity
public class Organization {
   @OneToMany(cascade=ALL)
   @JoinTable(
        name="ACTIVE_EMPLOYEES",
        joinColumns = @JoinColumn( name="ORGANIZATION_ID"),
        inverseJoinColumns = @JoinColumn( name="EMPLOYEE_ID")
   )
   List<Employee> employees;
   ...
}

但是 ,我不得不说,我认为用两个表来表示当前和存档的员工是一个坏主意。这对我来说听起来像是一种“软删除”的情况,最好使用表内标志(IS_ACTIVE 或其他东西)来处理。那么你就没有这些奇怪的抽象类来执行你的查询、具有相同类型数据的多个表等。这个策略的一些描述 is here

然后,您可以使用您已经获得的非连接表映射,并使用 @Where 注释将组织中的员工限制为 IS_ACTIVE 设置为 true 的员工。这种方法的一个例子 is here.

10-07 19:06
查看更多