After putting in a bunch of printlns to track these dynamic calls, I see that Hibernate is instantiating my Container object, setting all of the necessary items. However, it tries to set my MiscItem with the superclass and I do not know why. Below is the code for Container:
Code:
public class Container {
//instance variables omitted
public void setContainerId(Long id) {
System.out.println("containerId = " + id);
this.containerId = containerId;
}
public void setMiscItem(MiscItem item) {
System.out.println("miscItem = " + item);
this.miscItem = item;
}
public void setCoreItem(CoreItem item) {
System.out.println("coreItem = " + item);
this.coreItem = item;
}
public void setStockItem(StockItem item) {
this.stockItem = item;
}
I have an Item interface, an AbstractItem base class that implements Item, and the concrete classes MiscItem, StockItem and CoreItem (all extend AbstractItem).
The initial call to save the entire Container graph works and this is what shows in the table CONTAINER:
Code:
CONTAINER_ID MISC_ITEM_ID CORE_ITEM_ID STOCK_ITEM_ID
262144 131089 131085 131091
For the CONTAINER table, the MISC/CORE/STOCK_ITEM_IDs are foreign keys to the ITEM table. The corresponding ITEM table looks like this:
Code:
ITEM_ID ITEM_TYPE
131089 MiscItem
131085 CoreItem
131091 StockItem
Now when I load data from the database, it loads CoreItem just fine but blows up on MiscItem... Here's a more detailed stacktrace:
Code:
org.hibernate.property.BasicPropertyAccessor$BasicSetter set
SEVERE: IllegalArgumentException in class: com.test.domain.Container, setter method of property: miscItem
org.hibernate.property.BasicPropertyAccessor$BasicSetter set
SEVERE: expected type: com.test.domain.item.MiscItem, actual value: com.test.domain.item.AbstractItem$$EnhancerByCGLIB$$d5b62e6x
org.hibernate.event.def.DefaultLoadEventListener onLoad
INFO: Error performing load command
org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of com.test.domain.item.miscItem
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:104)
containerId = 262144
stockId = com.test.domain.item.StockItem@19fca0c
at org.hibernate.tuple.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:330)
at org.hibernate.tuple.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:191)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3343)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:129)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1785)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:2821)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:370)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:351)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:122)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:81)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:871)
at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:829)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:66)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:160)
at com.test.domain.Container$$EnhancerByCGLIB$$d8ed955.getCoreItem(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
With the system.outs, hibernate first tries to instantiate the Container object (correct containerId) and then populate it by calling all of the setter methods. The first call is to setStockItem() and that works fine. The second call is to setMiscItem() and this is where it blows up, telling me of a mismatch type with AbstractItem.
Since hibernate is doing everything behind the scenes, it is tough for me to figure out why hibernate is instantiating the AbstractItem class and setting it for MiscItem even though the tables show otherwise. Am I doing something wrong with the mapping?
Any help would be appreciated. Thanks!
-los