We have 2 tables (an active table and an archive table) which have the same structure (ex. Employee
and EmployeeArchive
). To be able to leverage common code to use results for both tables we have an abstract parent class that defines all the methods and annotations.
We like to be able to perform queries that will use the same query for both tables and union the results together.
We have another entity/table (ex. Organization
) with a onetomany
/manytoone
bidirectional relationship with Employee
; Organization
has a List
of Employee
s and every employee has an organization.
When getting the employees of an organization via the association we only want the employees from the active table not the archive.
Is there a way to achieve what we are attempting or a viable workaround?
We have tried various implementations of @MappedSuperclass
, @Entity
/@InheritanceType.TABLE_PER_CLASS
to try to achieve what we want. Each implementation would nearly achieve what we want but not completely. For example to be able to query both tables we could have an abstract parent Entity
with InheritanceType.TABLE_PER_CLASS
but then we could not have the mappedBy
relationship to Employee
in the Organization
. We can use a MappedSuperclass
as the parent to be able to have the correct relationship but then we cannot query both the Archive
and Active
tables via the union.
Here is basically what we are trying to layout:
@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;
...
}
Code
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;
}
We also tried to have the parent class extend the MappedSuperclass
and put the implementation and annotations in the MappedSuperclass
but we get an AnnotationException
for the relationship of the Organization
@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` ...
}
On deployment we get the following exception:
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)