具有id的对象不是指定的子类

时间:2014-08-27 17:26:36

标签: java mysql sql hibernate vtiger

我在申请时遇到了一个奇怪的错误 我试图通过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并创建会话。

我的地图错了吗?

3 个答案:

答案 0 :(得分:5)

您能告诉您在DB中有哪些数据记录吗?

看起来不同表之间的id具有相同的值,所以当hibernate试图加载具有特定id的实体时,如果内存中已经存在另一个具有相同id的实体,那么hibernate就会抱怨这个问题

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我遇到了相同的例外,但是出于完全不同的原因。

我们有实体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,并在代码中使用强制类型转换。

附加说明:这似乎可以工作几年,但是在架构更改后突然出现,在该架构中,休眠配置和任何类均未更改(我们只是重命名了一些软件包),然后直到删除后才消失具体的泛型类型。