0 Replies Latest reply on Dec 13, 2006 10:51 AM by Nico MACK

    How to correctly work with Many to One relationships.

    Nico MACK Newbie

      Hi...

      In the scope of a project we're working on, we're sometimes running into trouble with One to Many relationships. We've found two working scenarios but can't realy figure out whether they are "principaly correct" or not.

      Scenario 1
      ----------

      Lets assume a table parent and a table child, knowing that many child records may reference a single parent. (BTW we're using Postgres)

      CREATE TABLE parent
      (
      id SERIAL PRIMARY KEY,
      name VARCHAR(128)
      );

      CREATE TABLE child
      (
      id SERIAL PRIMARY KEY,
      parent_id INTEGER,
      name VARCHAR(128)
      );

      ALTER TABLE child ADD CONSTRAINT fk_parent_id FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE;

      In the parent Entity Bean, we have a property children, which is a collection, and which is mapped as follows:

      @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
      @JoinColumn(name = "parent_id")
      public Collection getChildren ()
      {
      return children;
      }

      In the Child Entity Bean, we have a parentId property of type Integer, which is mapped as follows:

      @Column(name = "parent_id", updatable=false, insertable=false)
      public Integer getParentId()
      {
      return parentId;
      }

      This scenario works fine as long as no NOT NULL constraints are being specified for the foreign key parent_id. It also fails as soon as the updatable and insertable attributes are removed from the child mapping.
      The advantage of this scheme is:
      We only have to add childs to the children collection an to perist the parent in order to store both the parent and the children. No need to previously set the parentId of the children.

      Scenario 2
      ----------

      Another scenario we have tried is as follows: Again the two tables (please note the addition NOT NULL constraint.

      CREATE TABLE parent
      (
      id SERIAL PRIMARY KEY,
      name VARCHAR(128)
      );

      CREATE TABLE child
      (
      id SERIAL PRIMARY KEY,
      parent_id INTEGER NOT NULL,
      name VARCHAR(128)
      );

      ALTER TABLE child ADD CONSTRAINT fk_parent_id FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE;

      In the parent Entity Bean, we have a property children, which is a collection, and which is mapped as follows:

      @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
      @JoinColumn(name = "parent_id")
      public Collection getChildren ()
      {
      return children;
      }

      In the Child Entity Bean, we have a parent property of type Parent, which is mapped as follows:

      @ManyToOne
      @JoinColumn(name="parent_id")
      public Parent getParent()
      {
      return parent;
      }

      Disadvantage of this solution is that we have to explicitly tell each child who his parent is.

      Question
      --------

      1.) Both solution appear to fail when it comes to deleting children, though. In both cases we have to explicitely determine which children are no longer require and we have to remove them explicitely. Are there other ways of using One to Many relationships ?

      2.) My guts tell me that the second scenario appears to be more "as intended by the inventor" or am I wrong ?

      Many thanks in advance for your help...