简体   繁体   中英

Hibernate: Getting org.hibernate.InstantiationException While Fetching polymorphic Collections in onetomany association

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 :

 @Cascade(value=org.hibernate.annotations.CascadeType.ALL)
 private Set<? extends Account> accounts = new HashSet<SavingsAccount>(); 

If you would like to add all future Sub Object of Account, then

 @Cascade(value=org.hibernate.annotations.CascadeType.ALL)
     private Set<? extends Account> accounts = new HashSet<Account>();

You should make the Account class a MappedSuperclass instead of an Entity . I didn't try it, so let me know, but that's how you deal with abstract classes with JPA annotations.

Reference: The Java EE 6 Tutorial : Entity Inheritance

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM