在不担心持久性的情况下,我设计了一个类来保存由(不同大小的)容器映射的不同产品的数量,这些容器可以保存在产品中。
class Inventory {
Long id;
Map <Long, Map<Long,Integer>> productQuantityByContainer; // ProductId->(ContainerId -> quantity)
}使用类作为
class Product {
Long id;
String name;
}
class Container {
Long id;
Double size;
}后两者对对应的数据库表有直接的Hibernate映射。我需要使用Hibernate映射文件(hbm.xml),并且我的数据库有以下信息(不考虑Hibernate的约束):
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映射。
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发布于 2016-12-01 07:36:30
经过许多磨难(没有答案),我找到了我自己的问题的解决方案。希望这能对将来的其他人有所帮助。我确实简化了我的设计,以摆脱Quantity类,因为ContainerQuantity中的映射可以只是一个值集合。但是,值得注意的是,没有Quantity类并不会阻止我们在数据库中拥有一个"Quantity“表。
// 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映射,结果是:
<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):
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);以下是驱动程序代码:
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);
}https://stackoverflow.com/questions/40856069
复制相似问题