簡體   English   中英

Hibernate生成的select語句具有兩個ID,實體ID值在加載時填充為null

[英]Hibernate generated select statement has two ids, entity id value populated with a null on load

我們有Hibernate Interceptor(擴展了EmptyInterceptor),它基於傳入的entityName在實例化時加載Spring類:

@Override
public Object instantiate(String entityName, EntityMode entityMode, Serializable id) {
    Object bean = null;
    String className = entityName.substring(entityName.lastIndexOf(".") + 1);
    StringBuffer entity = new StringBuffer(className.substring(0, 1).toLowerCase());
    entity.append(className.substring(1));
    String beanName = entity.toString();
            // Place any modified bean names here
    if ("policyType".equalsIgnoreCase(entity.toString())) {
        beanName = "policyTypeEntity";
    }

    if (this.applicationContext.containsBean(beanName)) {
        bean = this.applicationContext.getBean(beanName);
    }
    return bean;
}

基於此設置,當運行createCriteria查詢時,

this.policyInfo = (PolicyInfo) session.createCriteria(PolicyInfo.class).createAlias("quote", "q").add(Restrictions.eq("q.id", quoteId)).uniqueResult();

Hibernate如下生成所有SQL(節略的)(這只是急於初始化的子查詢之一):

 /* load one-to-many com.ipacc.onelink.model.entitybeans.PolicyInfo.persons */ select
    persons0_.POLICY_INFO_ID as POLICY_I5_35_1_,
    persons0_.ID as ID1_27_1_,
    persons0_.ID as ID1_27_0_,
    persons0_.WORK_ADDRESS_ID as WORK_ADD2_27_0_,
    persons0_.HOME_ADDRESS_ID as HOME_ADD3_27_0_,
    persons0_.MAIL_ADDRESS_ID as MAIL_ADD4_27_0_,
    persons0_.POLICY_INFO_ID as POLICY_I5_27_0_,
    persons0_.HOMEOWNER_VERIFIED as HOMEOWN26_27_0_ 
from
    COMBO21_OWNER.PERSON_INFO persons0_ 
where
    persons0_.POLICY_INFO_ID=?

如果您注意到,ID列將重復兩次,從而將實際的class屬性設置為null。

這里是PersonInfo實體開始的樣子:package com.ipacc.onelink.model.entitybeans;

import javax.persistence.Transient;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@SuppressWarnings("serial")
@Component
@Scope("prototype")
public class PersonInfo extends DomainObject implements Comparable<PersonInfo> {
private Address workAddress;
private Address homeAddress;
private Address mailAddress;
private PolicyInfo policyInfo;
private String firstName;
private String lastName;
private String middleName;
private String titlePrefix;
private String priorLastName;
private String ssn;
private Date birthDate;
private String ethnicGroup;
private String language;
and so on...

這繼承了如下所示的DomainObject:package com.ipacc.onelink.model;

import java.io.Serializable;

@SuppressWarnings("serial")
public class DomainObject implements Serializable {
protected Integer id;

public void setId(Integer id) {
    this.id = id;
}

public Integer getId() {
    return id;
}
}

添加簡化的映射文件:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.ipacc.onelink.model.entitybeans.PersonInfo" table="PERSON_INFO" schema="COMBO21_OWNER" dynamic-update="true" select-before-update="true">
    <id name="id" type="integer">
        <column name="ID" precision="10" scale="0" />
        <generator class="sequence">
            <param name="sequence">PERSON_INFO_SEQ</param>
        </generator>
    </id>
    <many-to-one name="workAddress" class="com.ipacc.onelink.model.entitybeans.Address" fetch="select"
        cascade="all">
        <column name="WORK_ADDRESS_ID" precision="10" scale="0" />
    </many-to-one>

有什么想法為什么會這樣?

謝謝

更新:我拉平了類以壓低id列,並如上所述刪除了DomainObject,但仍未取得任何進展。 因此,我們可以排除Hibernate繼承映射策略的問題(因為我不再使用祖先類)。 我也在Hibernate 4.2.7.SP1上進行了嘗試,因此我可以確認它也是先前版本中的問題。 我不認為這是一個Hibernate問題,而是使用實例化攔截器時Spring和Hibernate之間的握手問題。

這是我得到的重復ID:休眠:/ *加載一對多com.ipacc.onelink.model.entitybeans.PolicyInfo.installments * /選擇installmen0_.POLICY_INFO_ID作為POLICY_I2_35_1_,將installmen0_.ID作為ID1_18_1_,將installmen0_.ID作為ID ID1_18_0_,installmen0_.POLICY_INFO_ID作為POLICY_I2_18_0_,休眠:/ *加載一對多com.ipacc.onelink.model.entitybeans.PolicyInfo.policyQuestionAnswers * /選擇policyques0_.POLICY_INFO_ID作為POLICY_1_0_.Policy_0_.Policy_0_.Policy_0_.Policy_0_.Policy_0_.Policy_0_.Policy_0_.Policy_0_.Policy_0_.policy_0_.Policy_0_.policy_ID_ID作為POLICY_I2_0_。 ID1_37_1_,

有沒有人使用Hibernate EmptyInterceptor的實例化方法來實例化Spring bean並獲得成功?

我認為這是您的PersonInfo類中的映射問題。 您有3個不同的地址關聯。 我認為這是數據庫設計問題。 在這種情況下,外鍵關聯應由Address類或實體管理。 檢查如何實現此關聯。

另外,PersonInfo有一個關聯。 依賴關系。

public class PersonInfo extends DomainObject implements Comparable<PersonInfo> {
   private Address workAddress;
   private Address homeAddress;
   private Address mailAddress;
   private PolicyInfo policyInfo;

因此,檢查映射是否可能是一個問題,如果不是,請檢查Spring是否能夠使用攔截器機制解決這種遞歸依賴性。 我不知道,但這可能是個問題。

嘗試簡化您的PersonInfo映射,並檢查它是否可以正常使用Spring和Interceptor機制。

我想我有可能的答案。 您沒有為DomainObject和PersonInfo關聯提供繼承策略。

檢查繼承策略及其要求。 似乎在默認繼承策略的情況下,您的PersonInfo類需要一個附加的Id屬性。

存在以下策略

  • 每個類層次結構表
  • 每班桌
  • 每個具體類別的表

我認為您的映射不提供任何繼承策略定義。 另外,您可以使用基於注釋的映射進行這種繼承。 但是您使用xml映射,在我看來您沒有定義該關聯。

另外,我認為您嘗試使用對PersonInfo引用的遞歸依賴關系來解決此繼承依賴關系。 但這只是一個假設。

因此,這應該是為什么有兩個id的原因。 DomainObject表的一個ID和PersonInfo表的一個ID。 檢查您是否具有對PersonInfo施加外鍵約束的DomainObject或檢查繼承策略。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM