【问题标题】:Provided id of the wrong type hibernate提供了错误类型休眠的 id
【发布时间】:2012-06-04 00:32:08
【问题描述】:

我收到错误:

org.hibernate.TypeMismatchException:为类 BEntity 提供了错误类型的 id。预期:BEntity 类,获得 AEntity 类

public class BEntity implements Serializable{
    @Id
    @Column(name = "NUM")
    private String num;

    @Id
    @Column(name = "INIT")
    private String init;

    @Column(name = "V_CNT")
    private Integer vcnt;

   //{{{some column omitted}}}//
}

public class AEntity implements Serializable{

    @Id
    @Column(name = "NUM")
    private String num;

    @Id
    @Column(name = "INIT")
    private String init;

    @OneToOne
    @PrimaryKeyJoinColumns({
        @PrimaryKeyJoinColumn(name="NUM", referencedColumnName="NUM"),
        @PrimaryKeyJoinColumn(name="INIT", referencedColumnName="INIT")
    })
    private BEntity bEntity;
}

HQL 查询:

String queryString = "FROM AEntity AS A " +
                     "LEFT JOIN A.bEntityAS B " +
                     "WHERE A.INIT||A.NUM IN (:carList) AND A.INIT IN (:initList) AND A.NUM IN (:numberList) " + 
                     "AND B.TRUK_AXL_CNT > 0";

休眠生成代码

select aentity0_.NUMBER as NUMBER4_0_, aentity0_.INITIAL as INITIAL4_0_, bentity_p1_.NUMBER as NUMBER5_1_, bentity_p1_.INITIAL as INITIAL5_1_, aentity0_.V_CNT as VCNT3_4_0_, aentity0_.EIN as EIN4_0_, aentity0_.TYP as TYP5_4_0_, aentity0_.TRUK_CNT as TRUK6_4_0_, bentity_p1_.TRUK_AXL_CNT as TRUK3_5_1_ from USR.aentity aentity0_ left outer join USR.bentity_PRIMARY bentity_p1_ on aentity0_.NUMBER=bentity_p1_.NUMBER and aentity0_.INITIAL=bentity_p1_.INITIAL 
where (aentity0_.INITIAL||aentity0_.NUMBER in (?,?,?)) 
and (aentity0_.INITIAL in (?,?,?)) 
and (aentity0_.NUMBER in (?, ?, ?))
and bentity_p1_.TRUK_AXL_CNT>0

当我在 SQL Explorer 中运行代码时,它只能在代码中运行导致问题...

【问题讨论】:

  • 您使用的是哪个 Hibernate 版本?您使用的是核心还是 JPA?在这里使用 JPA+Hibernate 4.1.3 进行了测试,结果很好(没有错误)。您确定错误是在选择上还是在代码的另一部分?
  • 使用的是休眠 4.1.2 核心

标签: java hibernate annotations type-mismatch


【解决方案1】:

看起来这是休眠版本 3.2.6 中的一个缺陷,仍未解决。遇到了这个JIRA

Hibernate 支持拥有多个 @Id,但似乎在一对一映射下失败,解决此问题的建议方法是使用单个 CompositeKey,这意味着您创建一个 PK 类

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;

@Embeddable
public class PKClass implements Serializable {

    @Column(name = "NUM")
    private String num;

    @Column(name = "INIT")
    private String init;

    //gettter setter here

}

然后在您的实体中使用它作为 ID

public class BEntity implements Serializable{

    @Id
    private PKClass pkClass = null;

    @Column(name = "V_CNT")
    private Integer vcnt;

   //{{{some column omitted}}}//
}

public class AEntity implements Serializable{

    @Id
    private PKClass pkClass = null;

    @OneToOne
    @PrimaryKeyJoinColumns({
        @PrimaryKeyJoinColumn(name="NUM", referencedColumnName="NUM"),
        @PrimaryKeyJoinColumn(name="INIT", referencedColumnName="INIT")
    })
    private BEntity bEntity;
}

【讨论】:

  • 您真的尝试过您的解决方案吗?我刚刚得到“com.sun.istack.SAXException2:在对象图中检测到一个循环。这将导致无限深的 XML”,但在我的情况下,OneToOne 关系是双向的。为什么使用@Id 而不是@EmbeddedId?
【解决方案2】:

我遇到了同样的问题。我有两个具有相同字段的独立 PK 课程。所以我删除了一个 PK,只在所有者和子实体中使用了一个。这样就解决了问题。

【讨论】:

  • 投票!有同样的错误,是因为这个。即使 pk 的类被标记为 @Embeddable,也有两个类具有相同的字段。
【解决方案3】:

我遇到了同样的问题。

开始情况

主表上的主键

        <composite-id name="id" class="model.E1Id">
        <key-property name="taxpayerId" type="int">
            <column name="TaxpayerID" />
        </key-property>
        <key-property name="year" type="int">
            <column name="Year" />
        </key-property>
    </composite-id>

明细表上的主键

 <composite-id name="id" class="model.E1dataFromTaxPayerFolderId">
        <key-property name="tid" type="int">
            <column name="tID" />
        </key-property>
        <key-property name="year" type="int">
            <column name="Year" />
        </key-property>
    </composite-id>

修复后 我更改了明细表的类 Composite-id 并像这样设置主表的类:

        <composite-id name="id" class="model.E1Id">
        <key-property name="tid" type="int">
                            <column name="tID" />
                    </key-property>
        <key-property name="year" type="int">
            <column name="Year" />
        </key-property>
    </composite-id>

之后有必要(如果您有不同的名称)在您的主键类(在我的情况下为 E1Id)中添加属性 tid(使用 getter 和 setter 方法)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    • 2012-02-16
    • 2012-03-17
    • 2016-07-07
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    相关资源
    最近更新 更多