![](/img/trans.png)
[英]Hibernate Id Sequence Resulting null in Entity having two columns with sequence
[英]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.