Reputation: 1173
I am not very experienced with JPA and was curious if the following is possible.
Say I have a class Project
as follows:
@Entity
public class Project {
@Id
private String projectCode;
private String departmentId;
/*
* Is something like this possible with JPA?
*/
if (departmentId == null) {
@JoinColumn(name = "projectCode", referencedColumnName = "assignedProject")
} else {
@JoinColumn(name = "departmentId", referencedColumnName = "id")
}
@OneToMany(targetEntity = Employee.class)
private List<Employee> contributors;
// getters/setters
}
So I would like to populate the contributors
list based on the presence of departmentId
.
Is this possible with JPA? Or will I have to specify two List<Employee>
fields, mapped by both variables, and preform proper checks within my application logic?
Thanks for your help.
Upvotes: 0
Views: 757
Reputation: 10084
/*
* Is something like this possible with JPA?
*/
if (departmentId == null) {
@JoinColumn(name = "projectCode", referencedColumnName = "assignedProject")
} else {
@JoinColumn(name = "departmentId", referencedColumnName = "id")
}
No, this isn't possible with JPA and you'll be glad that it isn't.
You can achieve what you want by using inheritance in Java. Begin by creating an abstract
entity that contains all the common fields of your table. Then you can create an entity subclass with a projectCode
attribute and another entity subclass with a departmentId
attribute.
At the RDBMS level, for a simple object model like the one we just built, a single table can be mapped. In the abstract
entity, you would annotate as follows to achieve this:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE", discriminatorType = STRING, length = 1)
@DiscriminatorValue("?")
@Entity
public abstract class Project {
:
:
}
@DiscriminatorValue("P")
public class ProjectCodeProject extends Project {
:
:
}
Remember that RDBMS has no knowledge or notion of inheritance. Inheritance exists only on the Java side. In the database, inheritance is represented by metadata. The "Discriminator" is a special column (here named "DTYPE") that appears in your database table that informs JPA which subclass a particular column represents. In the above, the code "P" was chosen to represent database records that have a PROJECTCODE attribute rather than a DEPARTMENTID attribute.
Using a class hierarchy like this would enable you to have a table whose rows can have either a departmentId or a projectCode as an attribute (not both). Because rows of the table are all Projects
, developing common logic in Java to work with the subtypes ought to be relatively straightforward.
Upvotes: 1