I have a hierarchical mapping problem. Conceptually 3 elements
1. Product Definition -- high level definition about a product . A product can be STANDARD or COMPOSITE . A standard product has a list of specifications. Where as, a composite product consists of list of 2 or more intermediate products . One product can be part of one or more COMPOSITE . Hence Product Definition may be optionally hierarchical with many-to-many association to itself. One Product (STANDARD) can be part of multiple COMPOSITE products and COMPOSITE products may have 1 or more child products.
[Constraints : I have to keep both type of products as same Entity class. Ultimately going to be published as web services. So a single definitions / schema is preferred.]
2. Product Specification -- Detailed specification about product
3. Product Composition -- if a product is constituted by 1 or more intermediate products, this maintains the relationship. Composition has some other attributes too.
I have tried to following:
Code:
class ProductDefinition {
@ID
private Long id;
@Column(name="product_code")
private String productCode;
@Column(name="product_type")
private String productType; // STANDARD, COMPOSITE
@OneToMany(mappedBy="productDefinitionRef", cascade={CascadeType.ALL})
private Set<ProductSpec> productSpecs;
@OneToMany(mappedBy="childProductRef", cascade={CascadeType.ALL})
private Set<ProductComposition> compositionRefs; // For a standard product, lists the composites where the product belongs to
@OneToMany(mappedBy="parentProductRef", cascade={CascadeType.ALL})
private Set<ProductComposition> childProducts; // For a composite product, lists the proucts which are part of the composite
// ... other attributes
}
class ProductComposition {
@ID
private Long id;
private ProductDefinition
@ManyToOne
@JoinColumn(name="parent_prod_ref")
private ProductDefinition parentProductRef;
@ManyToOne
@JoinColumn(name="child_prod_ref")
private ProductDefinition childProductRef;
// ... Other attributes
}
class ProductSpec {
@ID
private Long id;
@ManyToOne
@JoinColumn(name="prod_def_ref")
private ProductDefinition productDefinitionRef;
// .. other attributes
}
Some sample data which I am expecting from the above model :
Product Definition
------------------
ID | Code | Type | productSpecs | compositionRefs | childProducts
1001 | P1 | STANDARD | [20001] | Empty | Empty
1002 | P2 | STANDARD | [20002] | [2001] | Empty
1003 | P3 | STANDARD | [20003] | [2001, 2002] | Empty
1004 | P4 | STANDARD | [20004] | Empty | Empty
2001 | B1 | COMPOSITE | Empty | Empty | [1002]
2002 | B2 | COMPOSITE | Empty | Empty | [1002, 1003]
Product Composition
-------------------
ID | parentProductRef | childProductRef
30005 | 2001 | 1002
30006 | 2002 | 1002
30007 | 2002 | 1003
Questions:
-----------
#1. Is this is an optimal way of mapping ? Please suggest if we can achieve anything better .
#2. Is this way of referencing the same composition entity twice within the product entity supported ? I am hitting some inconsistency when I see the data in the DB but before I discuss that, I want to make sure that atleast in theory this is feasible.