Home > Net >  How to properly do user favorites? JPA
How to properly do user favorites? JPA

Time:07-14

I'm trying to create a favorites mapping and I'm somewhat confused on how to do it, Here is my user class, for the sake of clarity it has only 2 bindings(1st one(file) - @OneToMany, 2nd one(favorite file) - @ManyToMany.

 @OneToMany(mappedBy = "app_user")
    @JsonIgnoreProperties("app_user")
    private List<File> file;

@ManyToMany(mappedBy = "app_user")
    @JsonIgnoreProperties("app_user")
    private Set<File> favorite_file;

And I've just realized that intellij complains about it for some reason. it tries to connect only to 1 field on the other side:

@JsonIgnoreProperties({"file", "profile"})
    @ManyToOne
    private AppUser app_user;

what would be a better way to do this? because Intellij complains about it and it works but only with native queries(since JPA claims that there is no difference between files and favorite files, but in native query there is a ManyToMany table so it works there)

My goal is to make users have favorite files distinct from files.

CodePudding user response:

It tries to connect only to 1 field on the other side

Well with @OneToMany(mappedBy = "app_user") you explicitly tell it to map it to the same field. Which doesn't make sense, because

  1. why would you have the same relation represented twice in one entity
  2. The relationship types don't match. You can't have one relationship be ManyToOne from the one side and in the inverse direction be ManyToMany

It looks you have some clarification to do on what you want to represent by your model. I see multiple possible variants.

The general mapping in AppUser is correct

So an AppUser has multiple File instances but each File is only owned by a single AppUser (if at all). But an AppUser favorites many files and each File might be favoured by many users.

@Entity
class AppUser {
    @OneToMany(mappedBy = "ownedBy")
    private List<File> files;

    @ManyToMany(mappedBy = "favoredBy")
    private Set<File> favoriteFiles;
}
@Entity
class File {
    @ManyToOne
    private AppUser ownedBy;

    @ManyToMany
    private Set<AppUser> favoredBy;
}

The important part is that the defining relationships (the one in File) are two distinct relationships. I removed the JSON annotations, because they are independent of the discussed problem.

Note that it is an interesting discussion if the relationship even should be bidirectional, but that is a different topic.

The favourite files are a subset of the owned files.

Then a more fitting model would be to model favouriting as an attribute of the relationship between AppUser and File

@Entity
class AppUser {
    @OneToMany
    private List<FileRelation> files;
eFiles;
}
@Entity
class FileRelation {
    @ManyToOne
    File file;

    boolean isFavourite;
}
@Entity
class File {
}

I made the relationships unidirectional and the overall relation between user and file a many to many. You might want to adapt that to your needs.

Side remark: Please use standard Java naming conventions when coding in Java (no snake case for attributes). Otherwise you are seriously hurting other Java developers.

  • Related