开发者

hibernate many to many mappings for join table with extra columns , surrogate key, additional primary key

I'm having hard time to resolve entity mappings (using annotations) for the following scenarios ( from legacy db)

Scenario 1:

Table A
  A_ID (PK)

Table B    
  B_ID (PK)

TABLE A_B    
  AB_ID (PK)  开发者_高级运维  
  A_ID (FK)    
  B_ID (FK)    
  Created_DATE

Scenario 2:

Table A    
  A_ID (PK)

Table B    
  B_ID (PK)

TABLE A_B    
  AB_ID (PK)    
  A_ID (PK)(FK)    
  Test_Date (PK)    
  B_ID (FK)    
  Created_DATE

Scenario 3:

Table A
  A_ID (PK)             
  A2_ID (PK)

Table B    
  B_ID (PK)

TABLE A_B    
  A_ID (PK)(FK)    
  A2_ID (PK)(FK)    
  B_ID (PK)(FK)   
  Created_DATE

Could some one kind enough to show these entities in hibernate using annotations and with explanation please?


Table Products
  Product_Id(PK)
  Product_Name
  Price

Table Orders
  Order_Id(PK)
  Order_Date
  Total

Table Order_Products
  Order_Id(FK)(PK)
  Product_Id(FK)(PK)
  Quantity

 @Entity
  public class OrderProducts{

     @Embeddable
     public static class IdClass {

        @ManyToOne
        @JoinColumn(name = "Product_Id")
        private Products p;

        @ManyToOne
        @JoinColumn(name = "Order_Id")
        private Orders o;
   }

   @Id
   private IdClass id = new IdClass();
   private Integer quantity;
  }

  @Entity
  public class Products{
     @ID
     private Integer id;

     @OneToMany(mappedBy="id.p") // this is the tricky part 'id.p'
     Set<OrderProducts> ops = new Set<OrderProducts>();

   }

similarly to Orders.


I will give you a similar scenario just for more clarity:

Scenario 1:

Table Products
   Product_Id(PK)
   Product_Name
   Price
Table Orders
   Order_Id(PK)
   Order_Date
   Total
Table Order_Products
   Order_Product_Id(PK) (Surrogate key)
   Order_Id(FK)
   Product_Id(FK)
   Quantity

In this domain we have a many-to-many relation between the Orders and Products tables as following:

  • An Order has many Products.
  • A Product may belong to many orders.

When we map this many to many relationship the Order_Products file mapping will not contain any implementation for this relation, it will be expressed by two many-to-many mappings(two bags or two sets from the two classes) in the two sides of the relation as follows:

For Products.hbm:

<class name="Products" table="Products">
   <id name="Product_Id" column="Product_Id">
       <generator class="native"/>
   </id>
   <bag name="Orders" generic="true" table="Orders_Products">
      <key column="Product_Id"/>
      <many-to-many column="Add_Orders_Id" class="Orders"/>
   </bag>
...and other properties
</class>

Orders.hbm:

<class name="Orders" table="Orders">
   <id name="Order_Id" column="Order_Id">
       <generator class="native"/>
   </id>
   <bag name="Products" generic="true" table="Order_Products">
       <key column="Orders_Id"/> 
       <many-to-many column="Product_Id" class="Products"/>
   </bag>
...

This means that the Product_Id from the Products table has a many to many relation with the Order_Id in the Orders table.

Notice that, the table in the bag tag is the many-to-many mapping table which is the intermediate point of the relation, and the Order_Id inside the bag is the FK in the Order_Products which relates to the Products table.

The names of the two bags are the names of the two collections in the two classes representing the many-to-many relations in the Products class:

    public virtual IList<Orders> Orders
    {
        get;
        set;
    }

In the Orders class you have a list of the products:

    public virtual IList<Products> Products
    {
        get;
        set;
    }

In the Order_Products.hbm you simply don't have to do anything for this relation, however you don't have to map the table Order_Products if it contains only the foreign keys and has no additional properties, e.g if it doesn't have the Quantity property:

  <class name="Order_Products" table="Order_Products">
    <id name="Order_Product_Id" column="Order_Product_Id">
      <generator class="native" />
    </id>
    <property name="Quantity" type="Decimal" column="Quantity" />
  </class> 

In the other two scenarios, I think you will follow the same mapping except you will use a composite-key(a <composite-id>) to map the additional compound primary key but the mappings will be the same.

For the two other scenarios, Honestly, I didn't try the mapping of a composite-id myself, but I think the relation will be in the same way and the composite key will not affect the relation, however the Hibernate team strongly does not recommend the use of the composite key.

I ignored a lot of code in the xml mappings just for simplicity.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜