我要求有一个抽象的超类。
我有6个子类用于该抽象超类。
我使用JPA中的SINGLE_TABLE继承策略映射它们。
在另一个POJO中,我与这些1 + 6课程有一对多的关系。
@OneToMany(mappedBy = "mSearchPreference", cascade = CascadeType.ALL)
private Set<SearchCriteria> mSearchCriteria;
这里“SearchCriteria”是抽象类。
@Entity
@Table(name = "SRCH_CRTR_T", schema = "LPEW")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "SRCH_DISCRIMINATOR_CDE", discriminatorType = DiscriminatorType.STRING)
@org.hibernate.annotations.ForceDiscriminator
public abstract class SearchCriteria extends BaseDBObject implements Comparable<SearchCriteria>
它有6个具体的子类类,如
@Entity
@DiscriminatorValue("DATE")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class SearchCriteriaDateRange extends SearchCriteria
我可以将值插入表中,但是当我检索时出现错误:
Caused by: org.hibernate.WrongClassException: Object with id: 261 was not of the specified subclass: com.lmig.lit.lpew.model.criteria.SearchCriteria (Discriminator: DATE )
at org.hibernate.loader.Loader.getInstanceClass(Loader.java:1453)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1284)
at org.hibernate.loader.Loader.getRow(Loader.java:1206)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:580)
at org.hibernate.loader.L
10:57:44,786 INFO [STDOUT] oader.doQuery(Loader.java:701)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
at org.hibernate.loader.collection.BatchingCollectionInitializer.initialize(BatchingCollectionInitializer.java:52)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:63)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.AbstractPersistentCollection.readElementExistence(AbstractPersistentCollection.java:142)
at org.hibernate.collection.PersistentSet.add(PersistentSet.java:187)
at com.lmig.lit.lpew.model.homescreen.HomeScreenPreference.addSearchCriteriaByType(HomeScreenPreference.java:132)
at com.lmig.lit.lpew.model.homescreen.HomeScreenPreference.addSearchCriteriaByType(HomeScreenPreference.java:147)
at com.lmig.lit.lpew.service.LpewUserServiceImpl.initializeHomeScreenPreferences(LpewUserServiceImpl.java:135)
at com.lmig.lit.lpew.service.LpewUserServiceImpl.findUserAndInitialize(LpewUserServiceImpl.java:103)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy122.findUserAndInitialize(Unknown Source)
at com.lmig.lit.lpew.jsf.beans.UserSession.getLpewUser(UserSession.java:989)
at com.lmig.lit.lpew.jsf.beans.RequestForServiceBean.getAllRequests(RequestForServiceBean.java:263)
at com.lmig.lit.lpew.jsf.beans.RequestForServiceBean.getAllNewRequests(RequestForServiceBean.java:382)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:64)
at org.apache.el.parser.AstValue.getValue(AstValue.java:97)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
有谁知道解决方案?
答案 0 :(得分:14)
您应该在根实体上使用@org.hibernate.annotations.DiscriminatorOptions(force=true)
答案 1 :(得分:6)
如果您正在加载一组SearchCriteria enities,那么您的堆栈跟踪就好像。
例如: @OneToMany(mappedBy =“mSearchPreference”,cascade = CascadeType.ALL) private Set mSearchCriteria;
问题是Hibernate在没有加载实体的情况下无法知道正确的子类。 因此,如果通过延迟加载创建集合,则hibernate首先为集合中的所有实体创建类型为SearchCriteria的代理。如果稍后加载了concreate实例,那么就无法通过正确的代理交换非concreate足够的代理。
因此,“修复”是不使用代理。 这意味着你要么必须这样做 使用预先加载(lazy =“false”)或 为lazy =“无代理”。后一种选择 需要字节码操作 编译类来制作Hibernate 拦截对getter的调用 方法(见 http://www.hibernate.org/hib_docs/v3/re ...属性)。我没有经验 用这种方法,但它似乎是一个 适合你案件的好人。
https://forum.hibernate.org/viewtopic.php?f=1&t=996047&start=0