I am trying to set up a simple mapping between two class hierarchies. An AssessmentPlanFamily (which is a subclass of DataPlanFamily) has a one-to-many relationship to AssessmentPlans (which is a subclass of DataPlan). To implement this relationship, I have the mappings on the superclasses (DataPlanFamily and DataPlan). Here is the code:
Code:
@Entity(name = "DataPlanFamily")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "TYPE_DISCRIMINATOR", length = 50)
@Table(name = "DATA_PLAN_FAMILY")
public abstract class DataPlanFamily implements IDataPlanFamily {
...
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "family", fetch = FetchType.EAGER)
@JoinColumn(name="FAMILY_ID")
private Set<DataPlan> plans = new HashSet<DataPlan>();
public Set<DataPlan> getPlans() {
return plans;
}
public void setPlans(Set<DataPlan> plans) {
this.plans = plans;
}
public void addPlan(DataPlan plan) {
// THERE CAN BE ONLY ONE!!!
if (!getPlans().contains(plan)) {
// Add the plan to this family's list of plans.
getPlans().add(plan);
// If this plan is already associated with another family, remove this plan from that
// family before adding it to this family. Note: this behavior of changing the family
// with which a plan is associated may not be provided at a higher level, but just in case.
if (plan.getFamily() != null) {
plan.getFamily().getPlans().remove(plan);
}
// Set the plan's family to this.
plan.setFamily(this);
}
}
...
}
@Entity(name = "DataPlan")
@Inheritance(strategy = InheritanceType.JOINED)
//@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "TYPE_DISCRIMINATOR", length = 50)
@Table(name = "DATA_PLAN")
public abstract class DataPlan implements IDataPlan {
...
@ManyToOne
@JoinColumn(name="FAMILY_ID", nullable = false)
@ForeignKey(name="FK_FAMILY_ID")
private DataPlanFamily family;
public DataPlanFamily getFamily() {
return family;
}
public void setFamily(DataPlanFamily family) {
this.family = family;
}
...
}
@Entity(name = "AssessmentPlanFamily")
@DiscriminatorValue("AssessmentPlanFamily")
public class AssessmentPlanFamily extends DataPlanFamily implements IAssessmentPlanFamily {
}
@Entity(name = "AssessmentPlan")
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "ASSESSMENT_PLAN")
@DiscriminatorValue("AssessmentPlan")
public class AssessmentPlan extends DataPlan implements IAssessmentPlan {
...
}
Here is the scenario that is casuing the problem:
1) I create an AssessmentPlanFamily, and then save it.
2) I go to modify that AssessmentPlanFamily by adding a Plan:
Code:
apfMaintenanceForm.getAssessmentPlanFamily().addPlan((DataPlan)apMaintenanceForm.getAssessmentPlan());
3) I then modify the Assessment Plan (apMaintenanceForm.getAssessmentPlan() ).
4) When I then try to save this Assessment Plan, this error gets thrown:
Code:
javax.ejb.EJBException: See nested exception; nested exception is: javax.persistence.PersistenceException: org.hibernate.InstantiationException: Cannot instantiate abstract class or interface: com.churchmutual.ocns.dataplan.model.jpa.DataPlanFamily
Any ideas what I'm doing wrong here?
Thanks,
Caleb