Home > Back-end >  Duplicating elements in a ManyToMany relation
Duplicating elements in a ManyToMany relation

Time:09-05

I have a ManyToMany relationship between Profile and ProfileExperience that is mapped as follows:

@ManyToMany
@JoinTable(name = "profile_experience_relations",
    joinColumns = {
            @JoinColumn(name = "profile_id")
    },
    inverseJoinColumns = {
            @JoinColumn(name = "profile_experience_id")
    })
private List<ProfileExperience> experiences;

I have added localization support inside of ProfileExperience, following this guide like so:

ProfileExperience Class

@OneToMany(mappedBy = "profileExperience", cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, orphanRemoval = true)
@MapKey(name = "localizedProfileExperiencePk.locale")
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
private Map<String, LocalizedProfileExperience> localizations = new HashMap<>();

LocalizedProfileExperience Class

@Entity
@Getter
@Setter
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class LocalizedProfileExperience {

    @EmbeddedId
    private LocalizedProfileExperiencePk localizedProfileExperiencePk;

    @ManyToOne
    @MapsId("id")
    @JoinColumn(name = "profileExperienceId")
    private ProfileExperience profileExperience;

    private String value;
}

Composite PK Class

@Embeddable
@Getter
@Setter
public class LocalizedProfileExperiencePk implements Serializable {
    private static final long serialVersionUID = 1L;

private String profileExperienceId;
private String locale;

public LocalizedProfileExperiencePk() {
}

Before adding the localization, there was no duplicate entries in the responses, however - everything retrieved is now duplicated. I can solve the issue by using a Set, however I'm curious as to why this happened. What is the explanation? Can I solve it without using a set? Am I overlooking something incredibly simple?

CodePudding user response:

Implement the equal method of your data class. Hibernate need it.

CodePudding user response:

The problem is that you are probably using join fetch or an entity graph to fetch nested collections. Now, when you look at the JDBC result set, you will see that there are many duplicate result set rows. If you have a profile with 2 profile experiences, and each has 3 localizations, you will see that you have 6 (2 * 3) duplicate rows. Theoretically, Hibernate could try to retain the expected object graph cardinality, but this is not so easy, especially when multiple collections are involved. Also, for certain collection mappings it would simply not be possible to do.

So the short answer to your problem is, never use a List unless duplicity matters to you. In this case, you will have an order column though, so even then it would be safe to use a list.

  • Related