【问题标题】:Discriminator , WrongClassException JPA with Hibernate backend带有 Hibernate 后端的鉴别器,WrongClassException JPA
【发布时间】:2010-12-02 10:58:45
【问题描述】:

我需要有一个抽象超类。

该抽象超类有 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)

有人知道解决办法吗?

【问题讨论】:

  • 是鉴别器的问题还是惰性初始化的问题?
  • 你如何加载实例,通过显式查询,或通过导航隐式抛出关联?是否涉及延迟加载?
  • 在关联中导航。我通过我正在加载的关系提到了那些创新的一对多关系,是的,我正在懒惰地加载实例。
  • 试试这个stackoverflow.com/q/42599203/4424739它对我有用。
  • 试试这个解决方案:stackoverflow.com/a/48788554/4424739 它对我有用。

标签: java hibernate jpa


【解决方案1】:

你应该在你的根实体上使用@org.hibernate.annotations.DiscriminatorOptions(force=true)

【讨论】:

  • 将@DiscriminatorOptions(force = true) 添加到超类对我有用,但我使用的是Hibernate 功能,而我更愿意留在JPA 方面。对此有什么建议吗?仅凭渴望获取并不能解决问题。
【解决方案2】:

您的堆栈跟踪看起来就像您正在加载一组 SearchCriteria 实体。

例如: @OneToMany(mappedBy = "mSearchPreference", cascade = CascadeType.ALL) 私有设置 mSearchCriteria;

问题是 Hibernate 在不加载实体的情况下无法知道正确的子类。 所以如果集合是通过延迟加载创建的,hibernate 首先为集合中的所有实体创建 SearchCriteria 类型的代理。如果 concreate 实例加载较晚,则无法通过正确的代理来交换未创建足够的代理。

因此,“修复”是不使用代理。 这意味着你要么必须 使用急切加载 (lazy="false") 或 懒惰=“无代理”。后一种选择 需要字节码操作 编译类以使 Hibernate 拦截对 getter 的调用 方法(见 http://www.hibernate.org/hib_docs/v3/re ... 特性)。我没有经验 用这种方法,但它看起来像一个 适合您的案例。

https://forum.hibernate.org/viewtopic.php?f=1&t=996047&start=0

【讨论】:

  • 另一方面,异常看起来还有其他问题 - 检查实体 261 的鉴别器列 - 它只是猜测:但异常包含一个空格。
  • 如果我保留 (fetch = FetchType.EAGER),我仍然会收到延迟初始化异常,但在我的应用程序中,所有其他延迟获取和急切获取都可以正常工作,但这是唯一的实例我们的应用程序中的继承映射,所以我在战斗。
  • 是的 DATE 有一个空格,我在 DATABASE 中更改了但仍然是同样的问题。
  • 我浏览了很多网站论坛,有些人提到使用强制鉴别器,我试过了,但 tat 也不起作用。
  • 现在(所有)空白都已修复,并且您将关联更改为 EAGER fetch - 您仍然得到相同的异常?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
  • 2010-11-19
相关资源
最近更新 更多