JPA复合外键错误

时间:2010-08-24 10:55:17

标签: jpa

在我的代码中,雇主与其费率表之间存在一对一的关系,其中雇主的复合主键是复合外国(逻辑上)+利率的主键。我正在使用JPA + hibernate + DB2。这是我的employer.hbm文件。

<hibernate-mapping>
    <class name="com.adg.ems.domain.Employer" table="EMPLOYER">
  </composite-id class="com.adg.ems.domain.EmployerIDClass" name="employerIDClass" >
   <key-property name="empID" type="java.lang.String" length="4" column="EMPLOYER_ID"></key-property>
   <key-many-to-one name="healthPlan" column="CUSTOMER_ID" class="com.adg.ems.domain.HealthPlan" lazy="false" access="property" >
   </key-many-to-one>
   <generator class="assigned" ></generator>
  </composite-id>  
  <property name="employerName" type="java.lang.String" length="50" not-null="true">
            <column name="EMP_NAME" />
        </property>        
  <property name="employerAddress1" type="java.lang.String" length="30" not-null="true">
            <column name="ADDR1" />
        </property>
        <one-to-one name="rate" class="com.adg.ems.domain.Rate"  cascade="all" lazy="false"/>

    </class>
</hibernate-mapping>



Rate.java

@Entity
@Table(name="RATES")
public class Rate extends IDomain {

 private static final long serialVersionUID = 123456698L;

 @Transient
 private Logger logger = LoggerFactory.getLogger(Rate.class);

 @EmbeddedId
 @GeneratedValue(generator = "foreign")
 @GenericGenerator(name = "foreign", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employer") })
 @AuditNotRequired
 private EmployerIDClass employerIDClass;

 @OneToOne(optional = false, cascade = CascadeType.ALL)
 @JoinColumns(value = {
   @JoinColumn(name = "EMPLOYER_ID", referencedColumnName = "EMPLOYER_ID", nullable = false, insertable = false, updatable = false),
   @JoinColumn(name = "CUSTOMER_ID", referencedColumnName = "CUSTOMER_ID", nullable = false, insertable = false, updatable = false)}) 
 @AuditNotRequired  
 private Employer employer;

 @Digits(fraction=5, integer=1, message="Must be number and of the form (+/-)#.#####, where '#' defines a numeric value.")
 @Column(name="RATE_APY")
    private Double rateAPY = 0.0;


 @Override
 public boolean equals(Object obj) {
  logger.debug("Inside EmployerRate equals method");
  if (obj != null && obj instanceof Rate) {
   Rate employerRate = (Rate) obj;
   EmployerIDClass employerIDClass = employerRate.getEmployerIDClass();
   logger.debug("employerIDClass ---->" + employerIDClass);
   if (employerIDClass != null) {
    if (employerIDClass.equals(this.employerIDClass)) {
     return true;
    }
   }
  }
  return false;
 }

 public int hashCode() {
  logger.debug("Inside EmployerRate hashcode method");
  return new HashCodeBuilder().append(getEmployerIDClass()).toHashCode();
 }


PKCLass

@Embeddable
public class EmployerIDClass extends IDomain {

 private static final long serialVersionUID = 123455793L;

 public EmployerIDClass() {
 }

 /**
  * Constructor
  * 
  * @param empID
  * @param healthPlan
  */
 public EmployerIDClass(String empID, HealthPlan healthPlan) {
  this.empID = empID;
  this.healthPlan = healthPlan;
 }

    @NotNull
    @Size(max = 3)
    @Column(name="EMPLOYER_ID", insertable=true, updatable=true, nullable=false)
    @AuditNotRequired
    private String empID;


    @NotNull
    @ManyToOne
    @JoinColumn(name="CUSTOMER_ID", insertable=true, updatable=true, nullable=false)
    @AuditNotRequired
    private HealthPlan healthPlan;
} 

Healthplan.hbm


<hibernate-mapping>
 <class name="com.adg.ems.domain.HealthPlan" table="CUSTOMER" >

  <id name="healthPlanID" type="java.lang.String" length="3" >
   <column name="CUSTOMER_ID" />
   <generator class="assigned" />
  </id>

  <timestamp name="addDate" column="ADDDATE" unsaved-value="null"></timestamp>

  <property name="healthPlanName" type="java.lang.String" not-null="true" length="50">
   <column name="NAME" />
  </property>

 </class>
</hibernate-mapping>

我的DAO类有findDomain方法

public Employer findDomain(IDomain iDomain) {
  EmployerIDClass employerIDClass = ((Employer) iDomain)
    .getEmployerIDClass();
  if (employerIDClass == null)
   return null;

try {
   Employer employer3 = entityManagerDB2JTA.find(Employer.class, employerIDClass);
   logger.debug("embeddedid workeddd."+employer3);
  } catch (Exception e) {
   logger.debug("embeddedid didntk work.", e);
  }

}

我得到的例外是:

INFO WebContainer : 1 org.hibernate.type.StringType - could not read column value from result set: employer1_28_1_; [IBM][CLI Driver] CLI0125E  Function sequence error. SQLSTATE=HY010


org.hibernate.util.JDBCExceptionReporter - could not load an entity: [com.adg.ems.domain.Employer#component[empID,healthPlan]{healthPlan=com.adg.ems.domain.HealthPlan#***, empID=***}] [select employer0_.employer_id as employer1_21_5_, employer0_.customer_id as customer2_21_5_, employer0_.emp_name as emp3_21_5_,  rate2_.employer_id as employer1_28_1_, rate2_.customer_id as customer8_28_1_, rate2_.rate_apy as rate2_28_1_ from dhs01.employer employer0_ left left outer join dhs01.rates rate2_ on employer0_.employer_id=rate2_.employer_id and employer0_.customer_id=rate2_.customer_id  where employer0_.employer_id=? and employer0_.customer_id=?]
COM.ibm.db2.jdbc.DB2Exception: [IBM][CLI Driver] CLI0125E  Function sequence error. SQLSTATE=HY010 at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.throw_SQLException(Unknown Source)
 at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.throw_SQLException(Unknown Source)
 at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.check_return_code(Unknown Source)
 at COM.ibm.db2.jdbc.app.DB2ResultSet.getString2(Unknown Source)
 at COM.ibm.db2.jdbc.app.DB2ResultSet.getString(Unknown Source)
 at com.ibm.ws.rsadapter.jdbc.WSJdbcResultSet.getString(WSJdbcResultSet.java:1848)
 at org.hibernate.type.StringType.get(StringType.java:41)
 at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:184)
 at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:173)
 at org.hibernate.type.AbstractType.hydrate(AbstractType.java:105)
 at org.hibernate.type.ComponentType.hydrate(ComponentType.java:583)
 at org.hibernate.type.ComponentType.nullSafeGet(ComponentType.java:298)
 at org.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:1121)
 at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:588)
 at org.hibernate.loader.Loader.doQuery(Loader.java:724)
 at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
 at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
 at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
 at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
 at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
 at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
 at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
 at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
 at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
 at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
 at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
 at org.hibernate.impl.SessionImpl.get(SessionImpl.java:842)
 at org.hibernate.impl.SessionImpl.get(SessionImpl.java:835)
 at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:182)
 at sun.reflect.GeneratedMethodAccessor382.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:618)
 at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
 at $Proxy528.find(Unknown Source)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:618)
 at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:224)
 at $Proxy506.find(Unknown Source)
 at com.adg.ems.dao.EmployerDAOImpl.findDomain_aroundBody26(EmployerDAOImpl.java:393)





WARN WebContainer : 1 org.hibernate.util.JDBCExceptionReporter - SQL Error: -99999, SQLState: HY010
ERROR WebContainer : 1 org.hibernate.util.JDBCExceptionReporter - [IBM][CLI Driver] CLI0125E  Function sequence error. SQLSTATE=HY010
INFO WebContainer : 1 org.hibernate.event.def.DefaultLoadEventListener - Error performing load command
org.hibernate.exception.GenericJDBCException: could not load an entity: [com.adg.ems.domain.Employer#component[empID,healthPlan]{healthPlan=com.adg.ems.domain.HealthPlan#002, empID=77V}]
 at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
 at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
 at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
 at org.hibernate.loader.Loader.loadEntity(Loader.java:1895)
 at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
 at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
 at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
 at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
 at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
 at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
 at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
 at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
 at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
 at org.hibernate.impl.SessionImpl.get(SessionImpl.java:842)
 at org.hibernate.impl.SessionImpl.get(SessionImpl.java:835)
 at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:182)
 at sun.reflect.GeneratedMethodAccessor382.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:618)
 at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
 at $Proxy528.find(Unknown Source)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:618)

请帮忙!!我被困住了..

1 个答案:

答案 0 :(得分:2)

问题在于DB2作为DB2(或者我怀疑是hibernate)返回String for String和Bigdecimal for Long。我必须在本机查询中使用DB2的cast()函数来获取记录。 在开始时,我尝试修改DB2dialect以使字符类型的hibernate返回字符串,但它不起作用。 如果有人在使用带有JPA getSingleresult()方法的DB2 V8.x(AIX),那么他们将不得不使用DB2400Dialect作为rownumber()和over()函数不能使用该DB2版本。