1

My questions i about storing one-to-many relationship to database (as Programming a one-to-many relationship)

Lets assume the example: we have parent and children. Each parent record can have many childs.

// Db storage:
// id name

public class Parent {
    Set<Childs> mChilds;
    private long mId;
    private String mName;
    // etc

    public Parent(String name) {
        this.mName = name;
    }

    public static Parent load(id) {
        // query database for all Parent attributes
        Parent p = new Parent("somename");

        // now its time to load set of child (1)
        Set<Child> children = Child.loadChildren(p);
    }
}

// Db storage
// id name parent_ref

public class Child {
    private Parent mParent;
    private String mName;

    public Child(String name, Parent parent) {
        this.mName = name;
        this.mParent = parent;
    }

    // loads a child with specific Id
    public static Child load(long id) {
        // query db like 
        Cursor c = db.query("child_table", new String[] {"id", "name", "parent_ref"}, "id = ?", new String[] {String.valueOf(id)});

        // now we have a cursor, we can construct child!
        // Oh my God! I call Parent.load, that calls loadChildren(3)
        return new Child(c.getColumn("name"), Parent.load(c.getColumn("parent_ref")));
    }

    public static Set<Child> loadChildren(Parent parent){ 
        // fetch all child ids, that given parent has
        List<long> childIds = getAllIds(parent);

        // for each id load child (2)
        Child c = Child.load(childId);
    }
}

As you can see, I'd like to load parent by given Id. Parent's load function call child's loadlChildren (call (1)), which calls Child.load(call (2)), which calls Parent.load (3) because it needs to make a reference to parent!

So there are two major questions as Im new to java dev.

1) Are there any workarounds about this problems? what Im doing wrong? 2) My call to loadChildren will create n Parents (n references to n objects) instead of creating references to one object. What should I do?

Community
  • 1
  • 1
user1284151
  • 875
  • 4
  • 12
  • 23
  • 2
    You should avoid creating your own ORM solution, and use JPA instead, which does that, but in a really better, faster and standard way. – JB Nizet Nov 25 '12 at 10:41
  • this is just for training. not for real app – user1284151 Nov 25 '12 at 10:44
  • 2
    You need to keep track of the entities you have instanciated, for instance by storing them in a Map (indexed by their primary key). – Guillaume Nov 25 '12 at 10:44
  • +1 to JB Nizet. When there are compatible, efficient tools provided --we should make use of them, when we can :) [JPA 1 to Many](http://www.roseindia.net/jpa/eclipsejpaexamples/jparelationship/one-to-many.) – bonCodigo Nov 25 '12 at 10:46
  • @user1284151: training is fine, but I would still train myself in using JPA rather than train myself in developing a new ORM framework. +1 to Guillaume: this map is what is called the first-level cache in ORM frameworks. – JB Nizet Nov 25 '12 at 10:47
  • I've to disagree. Training means understand how thinks work. Anybody can learn how to use JPA in a couple of day. Not everybody can learn how JPA exactly works behind the scene. And when there is the need of something outside the framework, that is where the second type of persons can do the different. – Luigi Massa Gallerano Nov 25 '12 at 10:58

1 Answers1

0

Why don't you implement some kind of cache system (maybe with a Java HashMap) where you can put a parent and its children and instead of loading them anyway, load them only if they aren't already in the cache? And get a reference to them if they are alredy in the cache.

I'd also have a look at the: Flyweight pattern

Or another solution I can think is to implement another method in the Parent class: somethink like "loadOnlyParent()" which loads only the Parent (if not already loaded) without the children. And implement a lazy loading of the children (if not already loaded) only when necessary.

Luigi Massa Gallerano
  • 2,347
  • 4
  • 23
  • 25