I am trying to use JOINED inheritance strategy in Hibernate using JPA annotations. My Base class is abstract and have Many to One association with other entities. However I am getting Hibernate Exception: Cannot instantiate abstract class or interface. Following is my class structure:
Account.java
@Entity(name="BANK_ACCOUNTS")
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Account {
@Id
@Column(name="ACC_ID")
@SequenceGenerator(name="account_id_seq", sequenceName="BANK_ACCOUNT_ACC_ID", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="account_id_seq")
private Long id;
@Column(name="IS_ACTIVE")
@Type(type="yes_no")
private Boolean isActive;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ACC_BRANCH_ID")
private Branch branch;
}
SavingsAccount.java
@Entity(name="BANK_SAVINGS_ACCOUNT")
public class SavingsAccount extends Account{
@Column(name="CURR_BAL")
private BigDecimal currentBalance;
}
Branch.class
@Entity(name="BANK_BRANCH")
public class Branch {
@Id
@Column(name="BRANCH_ID")
@SequenceGenerator(name="branch_id_seq", sequenceName="BANK_BRANCH_BRANCH_ID", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="branch_id_seq")
private Long id;
@OneToMany(mappedBy="branch",orphanRemoval=true, fetch= FetchType.LAZY)
@Cascade(value=org.hibernate.annotations.CascadeType.ALL)
private Set<Account> accounts = new HashSet<Account>();
}
So whenever I try to get list of accounts held by branch using the following code I get the exception mentioned below:
Branch branch = (Branch) session.get(Branch.class, branchId);
SavingsAccount acc = new SavingsAccount();
acc.setBranch(branch);
branch.getAccounts().add(acc);
Exception trace:
org.hibernate.InstantiationException: Cannot instantiate abstract class or interface: : com.sapient.bank.entities.Account
at org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:114)
at org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:136)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.instantiate(AbstractEntityTuplizer.java:737)
at org.hibernate.persister.entity.AbstractEntityPersister.instantiate(AbstractEntityPersister.java:4761)
at org.hibernate.internal.SessionImpl.instantiate(SessionImpl.java:1427)
at org.hibernate.internal.SessionImpl.instantiate(SessionImpl.java:1415)
at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.hydrateEntityState(EntityReferenceInitializerImpl.java:235)
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(AbstractRowReader.java:107)
at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:129)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:138)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102)
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:100)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:693)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:92)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1933)
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:559)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:261)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:555)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:143)
at org.hibernate.collection.internal.AbstractPersistentCollection$3.doWork(AbstractPersistentCollection.java:336)
at org.hibernate.collection.internal.AbstractPersistentCollection$3.doWork(AbstractPersistentCollection.java:324)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:261)
at org.hibernate.collection.internal.AbstractPersistentCollection.readElementExistence(AbstractPersistentCollection.java:323)
at org.hibernate.collection.internal.PersistentSet.add(PersistentSet.java:200)
at com.sapient.bank.dao.AccountDao.createNewSavingsAcc(AccountDao.java:28)
at com.sapient.util.MainClass.main(MainClass.java:32)
Please help me understand what is wrong with my code. Its working fine if I remove abstract keyword, but I want to make Account class as abstract. Is there any way to achieve this?
You could try for the following syntax in Branch Entity if you would like allow SavingsAccount or Child of SavingsAccount:
If you would like to add all future Sub Object of Account, then