Cascading persistence through an inverse field

#1

Hi!

I was playing with cascading persistence with @ManyToMany and inverse @ManyToMany fields, and I noticed that I can only get cascading persistence in one direction. If the "owner" of the relationship is persistent, then objects that are added to the relationship are automatically made persistent. However, I can not get this to work the other way around. I would also like the relationship owner to be persisted if a persisted object is added on the owner side.

I have included a minimal example ( I make the assumption points can belong to multiple point collections). I removed transaction-related code to keep it simple.

@Entity
public class PointCollection {
    @ManyToMany(cascade={PERSIST, REFRESH, MERGE})
    private Set<Point> points = new HashSet<>();

    public void addPoint(Point p)
    {
        points.add(p);
    }
...
}

@Entity
public class Point {
    @ManyToMany(mappedBy="points", cascade={PERSIST, REFRESH, MERGE})
    private Set<PointCollection> pointCollections;
    ...
}

Scenario 1:

PointCollection col = new PointCollection();
em.persist(col);

col.addPoint(new Point(x, y)); // OK, the new point is automatically persisted because "points" is changed and cascaded

Scenario 2:

Point p1 = new Point(x, y);
em.persist(p1);

PointCollection col = new PointCollection();
col.addPoint(p1); // the PointCollection is NOT persisted!

 

Is this a limitation due to the fact that the reverse field is only recalculated when it is retrieved from the database? What would be the best way to achieve this? Would it perhaps be better to just maintain a regular link on both sides instead of using an inverse field?

Thank you for your help.

 

#2

It is the application responsibility (according to the JPA specification) to keep both sides of a bidirectional relationship synchronized on changes.

In practice, if you update the owner side only, it is usually fine, as the inverse (mapped by) side will be updated automatically when the object is retrieved (or refreshed) from the database after commit or flush.

You may try synchronizing the two sides of the bidirectional relationship in scenario 2 by setting the collection reference in the new point to the new collection. If cascading still fails then we should look into it further.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)

Post Reply

To post a reply and/or subscribe to update notifications - please login