Hi, 
I have two related simple class hierarchies with single table per class hierarchie strategy:
Payment (superclass), CreditcardPayment, MobilePayment
BasePrice (superclass), CreditcardPrice, MobilePrice
CreditCardPayment has an unidirectional one-to-many association with CreditCardPrice, and MobilePayment accordingly with MobilePrice.
Accessing a Payment e.g. with find() may result (it is not deterministic) in a WrongClassException when the associations are annotated for eager fetching (no problems with lazy fetching).
Quote:
org.hibernate.WrongClassException: Object with id: MP$2 was not of the specified subclass: de.mobileview.test.jpa.MobilePrice (loaded object was of wrong class class de.mobileview.test.jpa.CreditcardPrice)
The problem occured with hibernate 3.6 and 4.0.1.
Any help is appreciated.
Regards,
Gonne
Code:
@Entity 
public abstract class Payment implements Serializable {
    @Id private String id;
    public Payment() {}
    public Payment(String id) {
        this.id = id;
    }
}
@Entity
public class CreditcardPayment extends Payment implements Serializable {
    private String ccnumber;
    private String company;
    @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.PERSIST)
    public List<CreditcardPrice> prices = new ArrayList<>();
    protected CreditcardPayment() {}
    public CreditcardPayment(String id, String ccno, String company) {
        super(id);
        this.ccnumber = ccno;
        this.company = company;
    }
}
@Entity
public class MobilePayment extends Payment implements Serializable {
   private String mobileAddress;
   @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.PERSIST)
   public List<MobilePrice> prices = new ArrayList<>();
   
   protected MobilePayment() {}
   public MobilePayment(String id, String mobileAdr) {
       super(id);
       this.mobileAddress = mobileAdr;
   }
}
@Entity
public abstract class BasePrice implements Serializable {
       @Id private String id;
   protected int amount;
   
   protected BasePrice() {}   
   protected BasePrice(String id, int amount) {
       this.id = id;
       this.amount = amount;
   }   
}
@Entity
public class CreditcardPrice extends BasePrice implements Serializable {
   private String company;
   
   protected CreditcardPrice() {}   
   public CreditcardPrice(String id, int amount, String company) {
       super(id, amount);
       this.company = company;
   }   
}
@Entity
public class MobilePrice extends BasePrice implements Serializable {
   private String operator;
   
   protected MobilePrice() {}   
   public MobilePrice(String id, int amount, String operator) {
       super(id, amount);
       this.operator = operator;
   }   
}
public class JpaMain {
    private EntityManagerFactory emf;
    
    private EntityManager em;
    private EntityTransaction tx;
    
    
    public JpaMain() {
        emf = Persistence.createEntityManagerFactory("JpaTest");
        em = emf.createEntityManager();
        tx = em.getTransaction();
    }
    
    public void close() {
        if (em != null) {
            em.close();
        }
        emf.close();
    }
    
    private void create() {
        tx.begin();
        CreditcardPayment cc_pm;
        CreditcardPrice cc_pr;
        MobilePrice m_pr;
        MobilePayment m_pm;
        
        cc_pm = new CreditcardPayment("CC1", "54893423", "Machocard");
        cc_pr = new CreditcardPrice("CC$1", 12, "Wiesacart");
        cc_pm.prices.add(cc_pr);
        cc_pr = new CreditcardPrice("CC$2", 12, "Döners Club");
        cc_pm.prices.add(cc_pr);
        em.persist(cc_pm);
        
        m_pm = new MobilePayment("MP2", "+49171723737");
        m_pr = new MobilePrice("MP$2", 81, "Vodafone");
        m_pm.prices.add(m_pr);
        em.persist(m_pm);
        
        tx.commit();
    }
    private void query() {
        em.clear();     // clear cache
        
        Payment pm = em.find(Payment.class, "CC1"); // may result in WrongClassException
        System.out.println(pm);
        
        pm = em.find(Payment.class, "MP2");  // may result in WrongClassException
        System.out.println(pm);
    }
    
    public static void main(String[] args) {
        JpaMain main = new JpaMain();
        try {
            main.create();
            main.query();
        }
        finally {
            main.close();
        }
    }
}