jan
jan

Reputation: 4063

JPA - Setting bidirectional relationship -> Big overhead to load all elements from OneToMany-Collection?

Consider the following classes. The Parent class holds a list of Child classes in a OneToMany relation. If I want to establish the bidirectional relation, I have to add the child to the list of children of the parent and set the parent to the child.

To add the child to the children list of the parent, I first have to load the list of all the children. I think this is a big overhead if I have a big list of children and I don't actually need the children for anything.

Look at the example code. Can I optimize that or has JPA already some kind build in optimization for that kind of operation?

In this example I skipped the EntityManager code, but I think it's clear what the code should do.

This is the Child class:

@Entity
public class Child {

    Parent parent;

    @ManyToOne
    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }
}

This is the Parent class:

@Entity
public class Parent {


    List<Child> children;

    @OneToMany(mappedBy = "parent")
    public List<Child> getChildren() {
        return children;
    }

    public void setChildren(List<Child> children) {
        this.children = children;
    }
}

And this class sets up the bidirectional relation.

public class Tester {


    public static void main(String[] args) {

        // in a real application i would load that from the 
        // DB and it would maybe have already a lot of children
        Parent parent = new Parent(); 
        Child child = new Child(); //

        // Set bidirectional relation
        // Isn't this line a lot of overhead -> need to load all the children just to add an additional one?
        parent.getChildren().add(child); 
        child.setParent(parent);
    }
}

Upvotes: 0

Views: 647

Answers (2)

sk85
sk85

Reputation: 407

If the assoication is too large, then yous should map the fetch type to lazy and call fetch the child (by calling getter method within the session) only when child is required... Or go for unidirectional mapping...

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 692271

You don't have to set the other side of the association. You need to be aware that if this collection is already loaded, or if it's loaded before a flush is done, then it will be in an inconsistent state.

But it's often the case that you simply add a child to a parent in the transaction, without doing anything else, and updating the collection is, in this case, useless.

If the collection is so large, maybe the association shouldn't be bidirectional.

Upvotes: 2

Related Questions