These fields are mainly required to generate the relationships of underlying entities in JPA, so JPA can make queries and optimizations based on those relationships.
However, as is your case, it is not always necessary to have the references to the entities with which a certain entity is related.
For that there is an attribute of the JPA annotations that indicate relations between entities / tables ( @OneToOne
, @ManyToOne
, @OneToMany
, @ManyToMany
) called fetch
, which allows you to specify the way JPA loads u obtains from the database the entities related to an entity.
Fetching of Related Entities
There are two possibilities:
FetchType.LAZY - Delayed (or lazy) upload
It loads all the entities related to an entity at the moment in which the same entity is loaded, it does not matter that you never use them. For example:
@OneToMany(fetch=FetchType.EAGE)
FetchType.EAGER - Early load
Load entities related to an entity ONLY when they are needed, that is, when you refer to that relationship by calling the list. For example:
@OneToMany(fetch=FetchType.LAZY)
It is worth mentioning that the default fetchType for the relations to-One ( @OneToOne
, @ManyToOne
) is EAGER and for the relations a-Many ( @OneToMany
, @ManyToMany
) is LAZY.
Why is it important?
In a single word: Performance. An early load will require an additional query to the database by JPA, which translates into a delay when loading the root entity. On the other hand, a delayed load will make the root entity load faster, but there will be a delay when using the entities related to that entity. Of course, the duration of these delays are almost always milliseconds or less, everything depends on the number of records related to the root entity, perhaps from tens of thousands of records that delay can be perceived.
To give you a direct answer to your question.
You must leave the @ManyToMany relationships.
However, if you are not going to need to get the characters that use that spell, leave the FetchType in LAZY in the entity% Character
relation. Although by default it already has FetchType.LAZY
, so you can leave it as it is.
@ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@JoinTable(
name = "characterSpells",
joinColumns = { @JoinColumn(name = "characterId") },
inverseJoinColumns = { @JoinColumn(name = "spellId") }
)
List<Spell> spells = new ArrayList<>();
And for the entity Spell
if you must specify to change the FetchType to EAGER. (I guess you'll need to know from the moment you create the Character
that Spell
s you can use).
@ManyToMany(mappedBy = "spell", fetch = FetchType.EAGER)
private List<Character> characters;