JPA: Resolving "Muliple respresentations of the same entity" while still permitting merging

Viewed 23

So, I know this question has been asked a lot, but I haven't seen it asked about a case like this.

I have the following entities:

@Entity
public class A {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(updatable=false)
    private Integer id;

    @OneToMany(mappedBy="a", cascade=CascadeType.ALL)   
    private List<B> bs;
}

@Entity
public class B {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(updatable=false)
    private Integer id;

    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(
        name="BToC"
        , joinColumns={
            @JoinColumn(name="BId", referencedColumnName="id")
            }
        , inverseJoinColumns={
            @JoinColumn(name="CId", referencedColumnName="id")
            }
        )
    private List<C> cs;
}

@Entity
public class C {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(updatable=false)
    private Integer id;

    @ManyToMany(mappedBy="cs",cascade=CascadeType.ALL)
    private List<B> bs;
}

If you had an A, a1, containing two B's with id's 1 and 2 respectively (let's call them b1 and b2), each containing a single C with id 1 (let's call them c1 and c2), that would make c1 and c2 each have a bs list containing b1 and b2. When trying to merge A, the merge cascades to b1 and b2, and each of the B's merges then cascade to c1 and c2. Since c1 and c2 have identical contents, I would expect the following result to be pushed to table BtoC:

BId | CId
----------
  1 |   1
  2 |   1

However, the merge fails because c1 and c2 both represent the same entity but are technically different objects.

So, my question is this: Is there a change I can make to allow merges applied to either A, B, or C to succeed and cascade, while permitting cases like with c1 and c2 where the contents are identical but the Object is different? Or would I need to omit the Merge Cascade Type from at least one of the entities, and have merges I would like to "cascade" from one object to another be handled manually (i.e. iterate through each entity, merging only those whose contents have not been previously merged OR assigning objects with identical contents to a single reference)?

1 Answers

Ok, seems like the fix was pretty simple, I just needed to implement a proper equals method for C class. Using that, I'm guessing JPA was able to determine that both representations were identical, and had no problems merging them.

Hoping this works for anyone else running into a similar issue.

Related