【问题标题】:Object with id was not of the specified subclass具有 id 的对象不属于指定的子类
【发布时间】:2014-08-27 17:26:35
【问题描述】:

我的应用程序出现奇怪的错误。
我正在尝试使用session.createCriteria().list() 从数据库(MySQL)中检索实体列表,但我得到了这个org.hibernate.WrongClassException

我已经查过这个错误,我知道它的含义,但我不知道如何根据我的上下文来解决它。

我有以下数据库结构:

CREATE TABLE vtiger_crmentity (
`crmid` int(19) NOT NULL
)

CREATE TABLE vtiger_account (
    `accountid` int(19) NOT NULL DEFAULT 0
)

CREATE TABLE vtiger_accountscf (
    `accountid` int(19) NOT NULL DEFAULT 0
)

CREATE TABLE vtiger_accoutshipads (
`accountaddressid` int(19) NOT NULL DEFAULT 0
)

CREATE TABLE vtiger_accountbillads (
    `accountaddressid` int(19) NOT NULL DEFAULT 0
)

所以,快速解释一下,所有表都由这些 id 列链接,在最后一级,vtiger_accountscf 表有 1 个vtiger_accountshipads 和 1 个vtiger_accountbillads。所有表的 PK 相同。
所以我把我的课程变成了这样(存根):

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "vtiger_crmentity")
public class VtigerCrmentity {
  @Id
  @Basic(optional = false)
  @Column(name = "crmid", nullable = false)
  public Integer getId() {
    return this.id;

  }
}


@Entity
@PrimaryKeyJoinColumn(name = "accountid")
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "vtiger_account")
public class VtigerAccount extends VtigerCrmentity {

}

@Entity
@PrimaryKeyJoinColumn(name = "accountid")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "vtiger_accountscf")
public class VtigerAccountscf extends VtigerAccount {
}

@Entity
@PrimaryKeyJoinColumn(name = "accountaddressid")
@Table(name = "vtiger_accountbillads")
public class VtigerAccountbillads extends VtigerAccountscf {
}

@Entity
@PrimaryKeyJoinColumn(name = "accountaddressid")
@Table(name = "vtiger_accountshipads")
public class VtigerAccountshipads extends VtigerAccountscf {
}

这是我的问题。当我这样做时:

getSession().createCriteria(VtigerAccountbillads.class).list();

我遇到了异常:

org.hibernate.WrongClassException: Object with id: 11952 was not of the specified subclass: VtigerAccountbillads (loaded object was of wrong class class VtigerAccountshipads)
    at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1391)
    at org.hibernate.loader.Loader.getRow(Loader.java:1344)
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:611)
    at org.hibernate.loader.Loader.doQuery(Loader.java:829)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    at org.hibernate.loader.Loader.doList(Loader.java:2533)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
    at org.hibernate.loader.Loader.list(Loader.java:2271)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
    at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)

由于项目限制,我没有使用 spring 或任何类似的东西来配置 Hibernate 并创建会话。

我的映射错了吗?

【问题讨论】:

  • all the tables are linked by the these id columns -- 所以你的意思是说所有表的 id 值都相同?你也能澄清一下in the last level, the vtiger_accountscf table has 1 vtiger_accountshipads and 1 vtiger_accountbillads.是什么意思吗
  • 是的,表中的 id 相同。我的意思是vtiger_accountsvtiger_accountbilladsvtiger_accountshipads 结合在一起(这是给定帐户的地址)

标签: java mysql sql hibernate vtiger


【解决方案1】:

除了@Chaitanya 在使用 persistence.xml 时的答案检查之外,还存在该实体的映射。

【讨论】:

    【解决方案2】:

    我遇到了同样的异常,但原因完全不同。

    我们有实体 A、B 和 C。B 和 C 扩展 A,A 是抽象的,我们使用 SINGLE_TABLE 继承。

    我们还有具有相同属性的实体 X、Y 和 Z(Y 和 Z 扩展 X,X 是抽象的,我们使用 SINGLE_TABLE 继承)。

    X 有一个 A 字段,属于泛型 A:

    public abstract class X<T extends A> {
        @ManyToOne
        T field;
    }
    

    Y和Z分别指定B和C的类型:

    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    @DiscriminatorValue(value = "Y")
    public abstract class Y extends X<B> {
    }
    

    我们有其他类在没有指定具体类型的情况下实现 X(保持 )——即使数据库中没有 Y 或 Z(这意味着 Hibernate 永远不必加载任何对象,实际上也不应该创建对象 Y或 Z)我们(有时)会得到一个 org.hibernate.WrongClassException。我们的解决方案是从类 Y 和 Z 中删除具体类型 B 和 C,并在我们的代码中使用强制类型转换。

    附加说明:这似乎工作了好几年,但在架构更改后弹出,其中休眠配置和任何类都没有更改(我们只是重命名了一些包),然后直到我们删除才消失具体的泛型类型。

    【讨论】:

      【解决方案3】:

      你能说出你在 DB 中有哪些数据记录吗?

      似乎不同表之间的 id 具有相同的值,因此当 hibernate 尝试加载具有特定 id 的实体时,如果内存中已经存在具有相同 id 的另一个实体,那么 hibernate 会抱怨这个问题。

      【讨论】:

      • 我不能,但是是的,他们有相同的 id。如果我将它们映射为单独的实体,而不扩展父实体,我可以绕过这个问题吗?
      • 嗯,不完全是答案,但您对相同 ID 的洞察力让我解决了我的问题。我从继承中删除了vtiger_accountbilladsvtiger_accountshipads,并将它们设为单表。由于我不会直接编辑或保存它们,这解决了我的问题。谢谢。
      • 感谢 Alberson 的 cmets,我还有一个问题,当您看到此问题时,您是否也在尝试加载 VtigerAccountshipads?因为这个问题只有在 Hibernate 的内存中有 2 个具有相同 id 的实体时才会出现。
      • 我试图加载所有VtigerAccountshipads 的列表。一个简单的session().createCriteria(VtigerAccountshipads.class).list()
      • 问题没有消除。你只是改变了模型。使用原始模型,问题仍然存在。
      猜你喜欢
      • 1970-01-01
      • 2017-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      相关资源
      最近更新 更多