如何将许多值类型集合映射到Hibernate中的单个表? [英] How to map many value type collections to one single table in Hibernate?

查看:64
本文介绍了如何将许多值类型集合映射到Hibernate中的单个表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于性能的原因,我试图将hibernate中的许多值类型集映射到一个表中。
首先,我把它们全部放在它们自己的表中,导致了太多的连接。



我有一个Categories类,包含许多组件然后使用entity-name和discriminator将它们映射到一个通过子类的表中。
请参阅下面的映射代码片段。



这可以正常工作,但由于包含所有集合的单个表格很难自动删除集合组件被删除。这是因为它被建模为一个实体,而Hibernate不能表示这个集合已被删除。



映射细节:

 < class name =com.sample.CategoriesDefaulttable =dec_cats> 
< id name =idcolumn =idtype =stringlength =40access =property>
< generator class =assigned/>
< / id>
< component name =incomeInfoMemberclass =com.sample.IncomeInfoDefault>
< property name =hasWagetype =booleancolumn =inMemWage/>
...
< component name =wageclass =com.sample.impl.WageDefault>
< property name =hasEmployerWagetype =booleancolumn =inMemEmpWage/>
...
< set name =employerWagescascade =all-delete-orphanlazy =false>
< key column =idCatsnot-null =true/>
<一对多实体名称=mIWaEmp/>
< / set>
< / component>
< / component>
< / class>

< class name =com.sample.NameValueTypeEntityMarkertable =cats_name_amount>
< id name =idcolumn =idtype =stringlength =40access =property>
< generator class =assigned/>
< / id>
< discriminator type =stringforce =true>
< column name =objTypeindex =ixDiscrCatsNameAmtlength =25not-null =true/>
< / discriminator>
< version name =versioncolumn =objVrsunsaved-value =negative/>

< subclass name =com.sample.NameAmountsIntValueTypeEntityMarker>
< property name =amount1type =integercolumn =amount1access =propertynot-null =true/>
...
< subclass entity-name =mIWaEmpname =com.sample.EmployerWageDefaultdiscriminator-value =mIWaEmp/>
< subclass entity-name =pIWaEmpname =com.sample.impl.EmployerWageDefaultdiscriminator-value =pIWaEmp/>
< / subclass>
< / class>

用法:

 分类cats = new CategoriesDefault(); 
工资工资=新工资();
Set< EmployerWage> set = new HashSet< EmployerWage>();
set.add(new EmployerWageDefault(cats));
wage.setEmployerWages(set);
IncomeMember inc = new IncomeMemberDefault();
inc.setWage(工资);
cats.setIncomeMember(inc);
cats.saveOrUpdate(); //将它存储在数据库中。

//现在删除收入:
cats.setIncomeMember(null);
cats.saveOrUpdate();
cats = getPersister()。findCats(cats.getId());
//错误:猫仍然包含收入成员,工资和雇主工资。

由于EmployerWage标记为类别的子类,因此不会自动删除此错误键列),所以他们被删除为孤儿的类别时被删除,而不是当他的组件被删除...
但是,我不能让EmployerWage工资的孩子作为工资是一个组件和休眠投诉那么......



Pffff ...很难解决这个问题。想法是更受欢迎的...

解决方案

不知道这是否会有所帮助,但你有没有尝试使用鉴别器列告诉Hibernate
根据表中的不同标准加载哪种值类型?




I am tring to map many value-type sets in hibernate to one table for performance reasons. First I did put them all in their own table which led to too many joins.

I have a Categories class that contains many components with a bunch of sets and then I map them to a single table through subclasses by using the entity-name and discriminator. See below for the mapping snippet.

This works fine, but because the single table that contains all the sets, it's hard to automatically remove a set when a component is removed. This is because it's modelled as an Entity and Hibernate can't signal that the set has been removed.

Mapping details:

<class name="com.sample.CategoriesDefault" table="dec_cats" >
 <id name="id" column="id" type="string" length="40" access="property">
  <generator class="assigned" />
 </id>
 <component name="incomeInfoMember" class="com.sample.IncomeInfoDefault">
   <property name="hasWage" type="boolean" column="inMemWage"/>
    ...
   <component name="wage" class="com.sample.impl.WageDefault">
     <property name="hasEmployerWage" type="boolean" column="inMemEmpWage"/>
      ...
     <set name="employerWages" cascade="all-delete-orphan" lazy="false">
      <key column="idCats" not-null="true" />
      <one-to-many entity-name="mIWaEmp"/>
     </set>
   </component>
 </component>
</class>

<class name="com.sample.NameValueTypeEntityMarker" table="cats_name_amount">
 <id name="id" column="id" type="string" length="40" access="property">
  <generator class="assigned" />
 </id>
 <discriminator type="string" force="true">
   <column name="objType" index="ixDiscrCatsNameAmt" length="25" not-null="true" />
 </discriminator>
 <version name="version" column="objVrs"  unsaved-value="negative"/>

 <property name="name" type="string" column="name" not-null="true" />
 <subclass name="com.sample.NameAmountsIntValueTypeEntityMarker">
  <property name="amount1" type="integer" column="amount1" access="property" not-null="true"/>
   ...
   <subclass entity-name="mIWaEmp" name="com.sample.EmployerWageDefault" discriminator-value="mIWaEmp" />
   <subclass entity-name="pIWaEmp" name="com.sample.impl.EmployerWageDefault" discriminator-value="pIWaEmp" />
 </subclass>
</class>

Usage:

Categories cats = new CategoriesDefault();
Wage wage = new Wage();
Set<EmployerWage> set = new HashSet<EmployerWage>();
set.add(new EmployerWageDefault(cats));
wage.setEmployerWages(set);
IncomeMember inc = new IncomeMemberDefault();
inc.setWage(wage);
cats.setIncomeMember(inc);
cats.saveOrUpdate(); // will store it in the db.

// now remove the income:
cats.setIncomeMember(null);
cats.saveOrUpdate();
cats = getPersister().findCats(cats.getId());
// ERROR: cats still contains IncomeMember, Wage and EmployerWages.

This errors occurs as the EmployerWages aren't automatically removed as they are marked as child's of Categories (see the key column) and so they are removed as orphan's when Categories is removed and not when of his components is removed... However, I can't make EmployerWages a child of Wage as Wage is a component and Hibernate complaints then...

Pffff... very hard to solve this. Idea's are more then welcome...

解决方案

Not sure if this will help, but have you tried using a discriminator column in order to tell Hibernate which value-type to load based on different criteria within the table?

http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/mapping.html#mapping-declaration-discriminator

这篇关于如何将许多值类型集合映射到Hibernate中的单个表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆