已有101人关注
复合主键 映射set集合
发表在Java图书答疑 2009-02-09
是否精华
版块置顶:
hibernate 应用开发完全手册 第9章 映射set
如果company为复合主键(id,companyName),应该如何映射?

一个主键是没有问题的:
<hibernate-mapping>
  <class name="com.formBean.Company" table="tb_company">

    <id name="id" column="id" type="int">
      <generator class="increment"/>
    </id>

    <property name="company_name" column="company_name" type="string" not-null="true"/>
    <property name="company_type" column="company_type" type="string" not-null="true"/>
    <property name="owner" column="owner" type="string" not-null="true"/>
    <property name="enrol_fund" column="enrol_fund" type="int" not-null="true"/>
    <property name="enrol_date" column="enrol_date" type="date" not-null="true"/>

    <set name="depts" table="tb_dept" cascade="all" lazy="false">
      <key column="company_id"/>
      <element column="name" type="string" not-null="true"/>
    </set>

  </class>
</hibernate-mapping>

复合主键出错Foreign key (FKA4F77D767347FFCD:tb_dept [company_id])) must have same number of columns
            as the referenced primary key (TB_COMPANY2 [ID,COMPANY_NAME]):
<hibernate-mapping>
    <class name="com.formBean.TbCompany2" table="TB_COMPANY2" schema="CIM">
        <composite-id name="id" class="com.formBean.TbCompany2Id">
            <key-property name="id" type="java.math.BigDecimal">
                <column name="ID" precision="22" scale="0" />
            </key-property>
            <key-property name="companyName" type="java.lang.String">
                <column name="COMPANY_NAME" length="50" />
            </key-property>
        </composite-id>
        <property name="companyType" type="java.lang.String">
            <column name="COMPANY_TYPE" length="50" />
        </property>
        <property name="owner" type="java.lang.String">
            <column name="OWNER" length="50" />
        </property>
        <property name="enrolFund" type="java.math.BigDecimal">
            <column name="ENROL_FUND" precision="22" scale="0" />
        </property>
        <property name="enrolDate" type="java.sql.Timestamp">
            <column name="ENROL_DATE" length="7" />
        </property>
        
    <set name="depts" table="tb_dept" cascade="all" lazy="false">
      <key column="company_id"/>
      <element column="name" type="string" not-null="true"/>
    </set>  
    </class>
分享到:
精彩评论 5
9527
学分:0 LV1
2009-02-12
沙发
我不知道你是怎么配置的,但你可以试试下面的代码:
<composite-id>   
    <key-property name="id" column="id" type="int" />   
    <key-property name="companyName" column="companyName" type="string" />   
</composite-id>   
 
garylyell
学分:0 LV1
2009-02-13
板凳
我的目的是这样的:

有两个表ITEMS_LEGACY,BIDS_LEGACY之间是一对多的关系,主键都是"NAMING_NAME","DWBH","CREATEDATE",
两个表之间通过非主键NAMIN_MRID和ITEMS_LEGACY进行关联。我需要在查询ITEMS_LEGACY表数据的时候,
同时把与之有关联的BIDS_LEGACY表数据也取出来。主键要求以主键类而不是实体类的方式实现。


CREATE TABLE "CIM"."ITEMS_LEGACY"
   ("NAMING_NAME" VARCHAR2(10),
"DWBH" VARCHAR2(10),
"CREATEDATE" DATE,
"NAMIN_MRID" VARCHAR2(10),
 CONSTRAINT "SVGHSNGa" PRIMARY KEY ("NAMING_NAME","DWBH","CREATEDATE")
)
/

CREATE TABLE "CIM"."BIDS_LEGACY"
   ("NAMING_NAME" VARCHAR2(10),
"DWBH" VARCHAR2(10),
"CREATEDATE" DATE,
"ITEMS_LEGACY" VARCHAR2(10),
 CONSTRAINT "SVFCSNGa" PRIMARY KEY ("NAMING_NAME","DWBH","CREATEDATE")
)
/

insert into ITEMS_LEGACY (NAMING_NAME, DWBH, CREATEDATE, NAMIN_MRID)
values ('电力营销', '9901', to_date('01-01-2009', 'dd-mm-yyyy'), '0001');
insert into ITEMS_LEGACY (NAMING_NAME, DWBH, CREATEDATE, NAMIN_MRID)
values ('数据上传', '9901', to_date('01-01-2009', 'dd-mm-yyyy'), '0002');
insert into ITEMS_LEGACY (NAMING_NAME, DWBH, CREATEDATE, NAMIN_MRID)
values ('移动评测', '9901', to_date('01-01-2009', 'dd-mm-yyyy'), '0003');

insert into BIDS_LEGACY (NAMING_NAME, DWBH, CREATEDATE, ITEMS_LEGACY)
values ('系统管理', '9901', to_date('01-01-2009', 'dd-mm-yyyy'), '0001');
insert into BIDS_LEGACY (NAMING_NAME, DWBH, CREATEDATE, ITEMS_LEGACY)
values ('电能计量', '9901', to_date('01-01-2009', 'dd-mm-yyyy'), '0001');
insert into BIDS_LEGACY (NAMING_NAME, DWBH, CREATEDATE, ITEMS_LEGACY)
values ('业扩报装', '9901', to_date('01-01-2009', 'dd-mm-yyyy'), '0001');
insert into BIDS_LEGACY (NAMING_NAME, DWBH, CREATEDATE, ITEMS_LEGACY)
values ('关联', '9901', to_date('01-01-2009', 'dd-mm-yyyy'), '0002');
insert into BIDS_LEGACY (NAMING_NAME, DWBH, CREATEDATE, ITEMS_LEGACY)
values ('封装', '9901', to_date('01-01-2009', 'dd-mm-yyyy'), '0002');
insert into BIDS_LEGACY (NAMING_NAME, DWBH, CREATEDATE, ITEMS_LEGACY)
values ('框架', '9901', to_date('01-01-2009', 'dd-mm-yyyy'), '0003');

commit;


如果是单主键的话,是可以实现的,配置如下:
ItemLegacy.hbm.xml:

<set name="bids" inverse="true" lazy="false" cascade="all-delete-orphan">
<key column="items_legacy" property-ref="naminMrid"/>
<one-to-many class="com.formBean.BidsLegacy"/>
</set>

BidLegacy.hbm.xml:

<many-to-one name="item" class="com.formBean.ItemsLegacy" column="items_legacy" property-ref="naminMrid" not-null="true"/>

由于关联的都是非主键字段,因此对于复合主键(我只试过主键类方式)也按照以上方式进行配置,但运行出错,情况是这样的:

ItemsLegacy.java:
  private ItemsLegacyId id;
  private String naminMrid;
  private Set bids;
  ......
ItemsLegacyId.java:
  private String namingName;
  private String dwbh;
  private Timestamp createdate;
  ......
ItemsLegacy.hbm.xml:
<hibernate-mapping>
    <class name="com.formBean.ItemsLegacy" table="ITEMS_LEGACY" schema="CIM">
        <composite-id name="id" class="com.formBean.ItemsLegacyId">
            <key-property name="namingName" type="java.lang.String">
                <column name="NAMING_NAME" length="10" />
            </key-property>
            <key-property name="dwbh" type="java.lang.String">
                <column name="DWBH" length="10" />
            </key-property>
            <key-property name="createdate" type="java.sql.Timestamp">
                <column name="CREATEDATE" length="7" />
            </key-property>
        </composite-id>
        <property name="naminMrid" type="java.lang.String">
            <column name="NAMIN_MRID" length="10" />
        </property>       
        <set name="bids" inverse="true" lazy="false" cascade="all-delete-orphan">
<key column="items_legacy" property-ref="naminMrid"/>
<one-to-many class="com.formBean.BidsLegacy"/>
</set>
    </class>
</hibernate-mapping>



BidsLegacy.java:
  private BidsLegacyId id;
  private String itemsLegacy;
  private ItemsLegacy item;
  ......
BidsLegacyId.java:
  private String namingName;
  private String dwbh;
  private Timestamp createdate;
  ......
BidsLegacy.hbm.xml
<hibernate-mapping>
    <class name="com.formBean.BidsLegacy" table="BIDS_LEGACY" schema="CIM">
        <composite-id name="id" class="com.formBean.BidsLegacyId">
            <key-property name="namingName" type="java.lang.String">
                <column name="NAMING_NAME" length="10" />
            </key-property>
            <key-property name="dwbh" type="java.lang.String">
                <column name="DWBH" length="10" />
            </key-property>
            <key-property name="createdate" type="java.sql.Timestamp">
                <column name="CREATEDATE" length="7" />
            </key-property>
        </composite-id>
        <property name="itemsLegacy" type="java.lang.String">
            <column name="ITEMS_LEGACY" length="10" />
        </property>       
        <many-to-one name="item" class="com.formBean.ItemsLegacy" column="items_legacy" property-ref="naminMrid" not-null="true"/>
    </class>
</hibernate-mapping>


错误是:
[org.hibernate.impl.SessionFactoryImpl] INFO -- Checking 0 named queries
------在时抛出异常,内容如下:
org.hibernate.PropertyAccessException: exception getting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) getter of com.formBean.ItemsLegacyId.?
at org.hibernate.tuple.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:42)
at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:257)
at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:158)
at org.hibernate.engine.EntityKey.getHashCode(EntityKey.java:68)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:41)
at org.hibernate.engine.PersistenceContext.getCollectionOwner(PersistenceContext.java:674)
at org.hibernate.loader.Loader.readCollectionElement(Loader.java:660)
at org.hibernate.loader.Loader.readCollectionElements(Loader.java:370)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:314)
at org.hibernate.loader.Loader.doQuery(Loader.java:412)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1434)
at org.hibernate.loader.collection.OneToManyLoader.initialize(OneToManyLoader.java:111)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:488)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1430)
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:280)
at org.hibernate.engine.PersistenceContext.initializeNonLazyCollections(PersistenceContext.java:796)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:223)
at org.hibernate.loader.Loader.doList(Loader.java:1593)
at org.hibernate.loader.Loader.list(Loader.java:1577)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:395)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:271)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:844)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:74)
at client.HibernateUtil.query(HibernateUtil.java:32)
at client.ClientApps.main(ClientApps.java:36)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to com.formBean.ItemsLegacyId
at com.formBean.ItemsLegacyId$$BulkBeanByCGLIB$$f1b86950.getPropertyValues(<generated>)
at net.sf.cglib.beans.BulkBean.getPropertyValues(BulkBean.java:48)
at org.hibernate.tuple.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:39)
... 26 more
Exception in thread "main" java.lang.NullPointerException
at client.ClientApps.main(ClientApps.java:38)

      
无语_mrkj
学分:3155 LV11
2009-02-16
地板
本论坛只能针对书中出现的问题进行回复,您的问题已经超出我们的服务范围!
garylyell
学分:0 LV1
2009-02-17
4L
这就是不负责任的表现了!
超出又怎么啦?还不是该书的内容不够全面,否则谁愿意跑这儿来浪费时间。而且你可以以后补充阿!
仅仅是一些基础的东西是不够的,最好能多一点能解决实际问题的东西。
如果是答复不了可以明说,也不用找借口把!
9527
学分:0 LV1
2009-02-19
5L
你在数据库中设置好主键之后,在Hibernate的反项工程里可以直接生成映射文件,你可以参考一下它的语法格试。其实在实际的开发当中映射文件都是生成的,手写效率很低,也很容易出错。
首页上一页 1 下一页尾页 5 条记录 1/1页
手机同步功能介绍
友情提示:以下图书配套资源能够实现手机同步功能
明日微信公众号
明日之星 明日之星编程特训营
客服热线(每日9:00-17:00)
400 675 1066
mingrisoft@mingrisoft.com
吉林省明日科技有限公司Copyright ©2007-2022,mingrisoft.com, All Rights Reserved长春市北湖科技开发区盛北大街3333号长春北湖科技园项目一期A10号楼四、五层
吉ICP备10002740号-2吉公网安备22010202000132经营性网站备案信息 营业执照