Issue
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.
Solution
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
- why would you have the same relation represented twice in one entity
- The relationship types don't match. You can't have one relationship be
ManyToOne
from the one side and in the inverse direction beManyToMany
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.
Answered By - Jens Schauder
Answer Checked By - Clifford M. (JavaFixing Volunteer)