Requirement Constraints

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Wednesday, 1 August 2012

Hibernate Mapping one to Many–Some useful explanation from the internet

Posted on 10:06 by Unknown

Example 1-59 @OneToMany - Customer Class With Generics

@Entity
public class Customer implements Serializable {
    ...
    @OneToMany(cascade=ALL, mappedBy="customer")
    public Set<Order> getOrders() {
        return orders;
    }
    ...
}

Example 1-60 @ManyToOne - Order Class With Generics

@Entity
public class Order implements Serializable {
    ...
    @ManyToOne
    @JoinColumn(name="CUST_ID", nullable=false)
    public Customer getCustomer() {
        return customer;
    }
    ...
}

To understand this, you must take a step back. In OO, the customer owns the orders (orders are a list in the customer object). There can't be an order without a customer. So the customer seems to be the owner of the orders.

But in the SQL world, one item will actually contain a pointer to the other. Since there is 1 customer for N orders, each order contains a foreign key to the customer it belongs to. This is the "connection" and this means the order "owns" (or literally contains) the connection (information). This is exactly the opposite from the OO/model world.

This may help to understand:

public class Customer {
     // This field doesn't exist in the database
     // It is simulated with a SQL query
     // "OO speak": Customer owns the orders
     private List<Order> orders;
}

public class Order {
     // This field actually exists in the DB
     // In a purely OO model, we could omit it
     // "DB speak": Order contains a foreign key to customer
     private Customer customer;
}

The inverse side is the OO "owner" of the object, in this case the customer. The customer has no columns in the table to store the orders, so you must tell it where in the order table it can save this data (which happens via mappedBy).

The entity which has the table with foreign key in the database in owning entity and other side is inverse entity

*******************************************************************************************************************************************

Assume that we have 2 tables, ENQUIRY and ELEMENT with a One-to-Many relationship such that an Enquiry has many Elements. And if we want to enforce the NOT NULL constraint on foreign key column ELEMENT.ENQUIRY_ID. This relationship looks like so when modeling the Enquiry object with Hibernate:

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "ENQUIRY_ID", referencedColumnName = "ID")
private Set elements = new HashSet();

When you enforced the NOT NULL constraint at the database level you will received the following error

Caused by: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("ELEMENT"."ENQUIRY_ID")

So Hibernate is obviously persisting the collection of elements before the parent enquiry and then going back and doing an UPDATE on the foreign key field afterwards (so INSERT collection items with NULL foreign key, INSERT parent, UPDATE collection item foreign keys) as it doesn’t realise the foreign key column will always be non-null.

We must explicitly tell Hibernate that the foreign key column is NOT NULL. It can then persist the parent enquiry first followed by the collection items. To do this, add the following clause to the @JoinColumn annotation:

@JoinColumn(name = "ENQUIRY_ID", referencedColumnName = "ID", nullable = false)

This way, not only are you ensuring database best-practice, but Hibernate will also have to issue less statements (so INSERT parent, INSERT collection items) which should be a more efficient transaction statement.

*******************************************************************************************************************************************

Bidirectional One-To-Many
Let us create a Bidirectional One-To-Many relationship between Question and Choice, a Question has many choices.


  1. Setup entities

    @Entity
    @Table (name = "QUESTION")
    public class Question implements Serializable
    {

    @Id
    @GeneratedValue (strategy = GenerationType.AUTO)
    @Column (name = “QUESTION_ID”)
    private Long id;

    @Column (name = “TEXT”)
    private String text;
    ……………


    @Entity
    @Table (name = "CHOICE")
    public class Choice implements Serializable
    {

    @Id
    @GeneratedValue (strategy = GenerationType.AUTO)
    @Column (name = “CHOICE_ID”)
    private Long id;

    @Column (name = “TEXT”)
    private String text;
    ……………


  2. Setup the ONE side on Question – I read ONE Question has MANY CHOICE(S).
    Question

    @OneToMany (mappedBy="question")
    private Set choices = new HashSet();

    mappedBy – means “I am not the owner side”, I am mapped by question from the other side of the relationship. It will also not create the database column which makes sense, I would expect a foreign key on the CHOICE table instead.


  3. Setup the Many side on Choice – I read on Choice.java MANY Choice has ONE Question
    @ManyToOne
    @JoinColumn (name="QUESTION_ID")
    private Question question;

    the @JoinColumn indicate the owning side of the relationship, it is responsible for updating the database column. It will create the QUESTION_ID column on the CHOICE table


  4. Reversing the Relationship so that the owning side is the Question instead
    Question

    @OneToMany
    @JoinColumn (name = "QUESTION_ID")
    private Set choices = new HashSet();

    Choice

    @ManyToOne
    @JoinColumn (name="QUESTION_ID", updatable = false, insertable = false)
    private Question question;


  5. Finally we need to use a List instead of Set – so we can preserve the order of the Choice(s).Question

    @OneToMany (
    cascade = {CascadeType.ALL},
    fetch = FetchType.EAGER
    )
    @JoinColumn (name = "QUESTION_ID")
    @org.hibernate.annotations.Cascade(
    value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN
    )
    @org.hibernate.annotations.IndexColumn(name = "CHOICE_POSITION")
    private List choices = new ArrayList();

    Choice

    @ManyToOne
    @JoinColumn (name="QUESTION_ID", nullable = false, updatable = false, insertable = false)
    private Question question;

    the @org.hibernate.annotations.IndexColumn defines the colum CHOICE_POSITION that will be used to maintain the order of the list. Some how reversing the ownership is the only way to get the IndexColumn to work



*******************************************************************************************************************************************

Email ThisBlogThis!Share to XShare to Facebook
Posted in Hibernate Mapping | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • ZK Example for inline Editing with Add New and Delete
    I am quite impressed on this demo from ZK . But adding new record and delete existing record is missing as part of typical CRUD. So i thoug...
  • EDI 5010 Documentation 837 Professional - Loop 2010BB Payer Name
    2010BB Payer Name          In this loop, all the information will be taken from Insurance master screen. Take a look of our sample screen...
  • EDI 5010 Documentation–837 - BHT - Beginning of Hierarchical Transaction
    BHT – Beginning of Hierarchical Transaction Loop Seg ID Segment Name Format Length Ref# Req Value   BHT Beginning of Hier...
  • Hibernate Validator Example 2
    In this example, we will see some more validation constraints such as @email, @past, @length, etc. And also we will also define custom error...
  • ZK Passing Parameter between two files using MVVM–Part 1
    Overview This is the first series of articles about Passing parameter between two zul files using MVVM Design pattern .This article will fo...
  • MVVM Command annotation and Notify change example
    Here is an example, how to pass parameter on a zul through MVVM Command binding annotation. ZK URL http://books.zkoss.org/wiki/ZK%20Develo...
  • History of Present Illness
    HPI - One of the main component of Clinical History. What is an HPI ? The history of present illness (HPI) is a chronological description...
  • Patient Demographics
    Patient browse (search) is the key element for any EMR / PMS Software. In my past 15 years experience, i involved more than 5 times in desig...
  • ViewModel Class Java Annotation @Init, @NotifyChange, @Command
    In following sections we'll list all syntaxes that can be used in implementing a ViewModel and applying ZK bind annotation. The ZK binde...
  • Good Website Design Links
    Form Design Label Placement in Forms International Address Fields in Web Forms 40 Eye-Catching Registration Pages blog-comment-form-...

Categories

  • Billing Process
  • C Workbook
  • C++ Workbook
  • Eclipse Tips
  • EDI 5010
  • EMR Appointment Features
  • EMR Labs Stuff
  • EMR PMS Links
  • EMR Use cases
  • EMR Vital Sign
  • Good Website Design
  • Hibernate Criteria Queries
  • Hibernate Introduction
  • Hibernate Introduction Setup
  • Hibernate Mapping
  • Hibernate POC
  • Hibernate Validator
  • Hibernate–Java Environment setup
  • HPI
  • Java
  • Maven
  • MU Certification
  • NPI
  • PQRS
  • Practice Management System
  • Spring Security
  • Tech Links
  • Today Tech Stuff
  • zk
  • ZK Hibernate
  • ZK 5 Databinding
  • ZK Application
  • ZK Calling Another ZUL
  • ZK CheckBox
  • ZK CreateComponents
  • ZK CSS
  • ZK extended Components
  • ZK Foreach
  • ZK Forum Posts
  • ZK Framework
  • ZK Hibernate Setup
  • ZK ID Space
  • ZK Include
  • ZK Installation
  • ZK iReport
  • ZK Layout
  • ZK Listitem Pagination
  • ZK Message Box
  • ZK MVC
  • ZK MVC Combox Box
  • ZK MVC CRUD Examples
  • ZK MVC Listbox
  • ZK MVVM
  • ZK MVVM Combo
  • ZK MVVM CRUD
  • ZK MVVM ListBox
  • ZK Spring
  • ZK TextBox

Blog Archive

  • ►  2013 (105)
    • ►  December (3)
    • ►  September (7)
    • ►  August (13)
    • ►  July (1)
    • ►  June (11)
    • ►  May (3)
    • ►  April (14)
    • ►  March (19)
    • ►  February (21)
    • ►  January (13)
  • ▼  2012 (177)
    • ►  December (1)
    • ►  November (13)
    • ►  October (19)
    • ►  September (24)
    • ▼  August (26)
      • Hibernate Validator - Creating custom constraints ...
      • Hibernate Validator - Creating custom constraints...
      • Hibernate Validator Example 2
      • Hibernate Validator Examples
      • Hibernate Validator Example 1
      • ZK Examples Index Page
      • Hibernate n+1 problem
      • MVVM Command annotation and Notify change example
      • EMR Most Commonly used Vital sign
      • ZK Hibernate one to Many annotation mapping bidire...
      • EDI 5010 Documentation – 837 Professional GE Funct...
      • One to many mapping using bidirectional relationsh...
      • Sample HL7 Files
      • LAB Test Panels
      • EMR In-house Lab workflow
      • One to many mapping using bidirectional relationsh...
      • Hibernate–Java Environment setup
      • Hibernate Mapping one to Many–Some useful explanat...
      • EDI 5010 Documentation 837 Professional - Loop 233...
      • EDI 5010 Documentation 837 Professional - Loop 232...
      • EDI 5010 Documentation 837 Professional - Loop 230...
      • EDI 5010 Documentation 837 Professional - Loop 230...
      • EDI 5010 Documentation 837 Professional - Loop 230...
      • EDI 5010 Documentation 837 Professional - Loop 230...
      • EDI 5010 Documentation 837 Professional - Loop 230...
      • EDI 5010 Documentation – 837 Professional SE Trans...
    • ►  July (6)
    • ►  June (37)
    • ►  May (30)
    • ►  April (16)
    • ►  March (1)
    • ►  January (4)
  • ►  2011 (5)
    • ►  December (1)
    • ►  November (1)
    • ►  July (1)
    • ►  June (1)
    • ►  April (1)
  • ►  2010 (1)
    • ►  September (1)
Powered by Blogger.

About Me

Unknown
View my complete profile