首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何定义映射映射的hibernate映射

如何定义映射映射的hibernate映射
EN

Stack Overflow用户
提问于 2016-11-29 00:51:28
回答 1查看 590关注 0票数 1

在不担心持久性的情况下,我设计了一个类来保存由(不同大小的)容器映射的不同产品的数量,这些容器可以保存在产品中。

代码语言:javascript
复制
class Inventory {
  Long                             id;
  Map <Long, Map<Long,Integer>>    productQuantityByContainer; // ProductId->(ContainerId -> quantity)
}

使用类作为

代码语言:javascript
复制
class Product {
  Long  id;
  String name;
}

class Container {
  Long     id;
  Double   size;
}

后两者对对应的数据库表有直接的Hibernate映射。我需要使用Hibernate映射文件(hbm.xml),并且我的数据库有以下信息(不考虑Hibernate的约束):

代码语言:javascript
复制
Product table
--------------
ID|Name
1  Milk
2  Orange Juice

Container table
---------------
ID |Size(oz)
10  32  
11  64

Inventory table (first 2 columns form the PK)
---------------
Product-ID(FK) | Container-ID(FK) | Quantity
  1              10                   25
  1              11                   15
  2              10                   33

我的问题是:我知道Hibernate不允许持久化的集合映射。因此,要使Hibernate从我的库存类中持久化信息,只需进行如下的设计和映射就足够了吗?(我用两个同名的映射表创建了两个类ContainerQuantity和Quantity,如下所示)请在下面评论/检查我的hbm映射。

代码语言:javascript
复制
class Inventory {   // <--- Redesigned --->
  Long       id;
  Map <Long, ContainerQuantity>    cqsByProduct; // ProductId->ContainerQty
}

<class name="Inventory"> <!-- hbm mapping -->
   <id name="id"/>
   <map name="cqsByProduct">
      <key column="Inventory_ID" not-null="true"/>
      <map-key column="Product_ID"
      <one-to-many class="ContainerQuantity"/>
   </map>
</class>

Inventory table (in Database)
---------------
  id
 90210
 90211

class ContainerQuantity {
  Long                  id;
  Map<Long,Integer>     quantitiesByContainer;
}

<class name="ContainerQuantity"> <!-- hbm mapping -->
   <id name="id"/>
   <map name="quantitiesByContainer">
      <key column="CQ_ID" not-null="true"/>
      <map-key column="Container_ID"
      <one-to-many class="Quantity"/>
   </map>
</class>

ContainerQuantity table (for holding the cqsByProduct collection)
------------------------
   id     | Product_ID  | Inventory_ID (FK to collection owner)  
  101          1            90210
  102          1            90210
  103          2            90210

class Quantity {
  Integer               quantity;
  Container             container; 
  ContainerQuantity     cq;        
}

<class name="Quantity"> <!-- hbm mapping -->
    <composite-id>
       <key-many-to-one name="container" class="Container" column="Container_ID" />
       <key-many-to-one name="cq" class="ContainerQuantity" column="CQ_ID" />
    </composite-id>     
</class>

Quantity table  (for holding quantitiesByContainer collection)
--------------------
 Container_ID(FK) | Quantity | CQ_ID (FK to collection owner)
    10               25         101
    11               15         102
    10               33         103
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-01 07:36:30

经过许多磨难(没有答案),我找到了我自己的问题的解决方案。希望这能对将来的其他人有所帮助。我确实简化了我的设计,以摆脱Quantity类,因为ContainerQuantity中的映射可以只是一个值集合。但是,值得注意的是,没有Quantity类并不会阻止我们在数据库中拥有一个"Quantity“表。

代码语言:javascript
复制
// classes defined in package hibtest
public class Inventory {
  Long            id;
  String          name;
  Map <Product, ContainerQuantity>    cqsByProduct;

  public Inventory()
  //..getters and setters for each of above
}

public class ContainerQuantity {
   Long                  id;
   Inventory             inventory;
   Map<Container,Integer>     quantitiesByContainer;

   public ContainerQuantity()
  //..getters and setters for each of above
}

最困难的部分是正确执行Hibernate映射,结果是:

代码语言:javascript
复制
<hibernate-mapping>
  <class name="hibtest.Inventory" table="INVENTORY">
     <id name="id" column="INVENTORY_ID">
        <generator class="sequence">
            <param name="sequence">DON.NEXT_INVENTORY_ID</param>
        </generator>
     </id>
     <property name="name" column="name" type="string"/>
     <map name="cqsByProduct" inverse="true" cascade="all"> <!-- inverse=true ensures INVENTORY_ID in CONTAINERQUANTITY table is set by hibtest.ContainerQuantity -->
        <key column="INVENTORY_ID" not-null="true"/>
        <map-key-many-to-many column="PRODUCT_ID" class="hibtest.Product"/>
        <one-to-many class="hibtest.ContainerQuantity"/>
     </map>
  </class>

  <class name="hibtest.ContainerQuantity" table="CONTAINERQUANTITY">
     <id name="id" column="CQ_ID">
        <generator class="sequence">
            <param name="sequence">DON.NEXT_CONTAINERQUANTITY_ID</param>
        </generator>
     </id>

     <many-to-one name="inventory" class="hibtest.Inventory" column="INVENTORY_ID" not-null="true" /> <!-- column will be set when row inserted into CONTAINERQUANTITY table -->

     <map name="quantitiesByContainer" table="QUANTITY" cascade="all" > <!--  inverse is false so CQ_ID in QUANTITY will be set by ContainerQuantity -->
       <key column="CQ_ID" not-null="true"/>
       <map-key-many-to-many column="CONTAINER_ID" class="hibtest.Container"/>       
       <element column="quantity" type="int"/>
     </map>
  </class>
 </hibernate-mapping>

我的表看起来是这样的(Oracle sql):

代码语言:javascript
复制
create table product
(
  id               NUMBER(22) not null,
  name             VARCHAR2(32) not null);

create table container
(
  id             NUMBER(22) not null,
  name           VARCHAR2(32) not null);

create table inventory
(
 INVENTORY_ID             NUMBER(22) not null,
 name                     VARCHAR2(32) not null);

create table containerquantity
(
 cq_id                    NUMBER(22) not null,
 product_id               NUMBER(22),
 inventory_id             NUMBER(22));

create table quantity
(
 quantity                 NUMBER(10) not null,
 container_id             NUMBER(22) not null,
 cq_id                    NUMBER(22) not null);

以下是驱动程序代码:

代码语言:javascript
复制
private static void persist(Session session){
    Product product1 = new Product();
    Product product2 = new Product();       
    product1.setName("Apple");
    product2.setName("Milk");

    Container c1 = new Container();
    Container c2 = new Container();
    c1.setName("32 oz");
    c2.setName("64 oz");

    //-- Make container-qty1 and add 2 quantity entries into it
    ContainerQuantity cq1 = new ContainerQuantity();

    Map<Container,Integer>     quantitiesByContainer1 = new HashMap<Container,Integer>();

    quantitiesByContainer1.put(c1, Integer.valueOf(25));
    quantitiesByContainer1.put(c2, Integer.valueOf(15));
    cq1.setQuantitiesByContainer(quantitiesByContainer1);

    //-- Make container-qty2 and add 1 quantity entry into it
    ContainerQuantity cq2 = new ContainerQuantity();

    Map<Container,Integer>     quantitiesByContainer2 = new HashMap<Container,Integer>();

    quantitiesByContainer2.put(c1, Integer.valueOf(33));
    cq2.setQuantitiesByContainer(quantitiesByContainer2);

    //-- Make Inventory object 
    Inventory inv = new Inventory(); inv.setName("foods");
    Map <Product, ContainerQuantity>    cqsByProduct = new HashMap<Product, ContainerQuantity>();
    cqsByProduct.put(product1, cq1);
    cqsByProduct.put(product2, cq2);

    //-- Set back-reference to inventory on ContainerQuantity objects 
    cq1.setInventory(inv);
    cq2.setInventory(inv);

    inv.setCqsByProduct(cqsByProduct);      

    session.save(product1);
    session.save(product2);
    session.save(c1);
    session.save(c2);

    session.save(inv);      
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40856069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档