I'm using spring data JPA and have Player
, Score
entities. Player
has @OneToMany
relation to Score
(and @ManyToOne
from Score
to Player
). I save Player
to the database without specifying related scores. After that, I save Score
to the database, passing to the contructor a link to the Player
. Then in the same function, I read Player
entry, but it has no link to the Score
entry yet.
I have FetchType.LAZY
in my OneToMany
relation, so I need to use annotation @Transactional
in that function. I also tried to save player and score in the inner transaction(using propogation=Propogation.REQUIRES_NEW
) and read the player entry in an external transaction, but it doesn't help. I also tried to add CascadeType.ALL
- no effect. And i used flush()
method from JpaRepository
- doesn't help too.
But if I will save player and score in one controller method(using spring MVC), and read in another, the player will have a link to the score.
Edited: add code, Score in code is GamePlayerScore. All classes have lombok annotations @Getter
and @ToString
.
Player
@Temporal(TemporalType.DATE)
@NonNull
@Column(updatable = false)
private Date createdAt;
@Setter
@NonNull
@Column(unique = true)
private String nickname;
@OneToMany(mappedBy = "winner", cascade = CascadeType.REFRESH)
private Set<GameStatistic> gamesWon;
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH}, optional = false)
@JoinColumn
private PlayerStatistic stat;
@OneToMany(mappedBy = "player", cascade = CascadeType.REFRESH)
private Set<GamePlayerScore> scores;
@ManyToOne
@JoinColumn
private Game currentGame;
public Player(String nickname, Date createdAt) {
this.nickname = nickname;
this.createdAt = createdAt;
stat = new PlayerStatistic(0, 0, 0, this);
}
GamePlayerScore
@ManyToOne(optional = false)
@JoinColumn
@NonNull
@JsonIgnore
private GameStatistic game;
@ManyToOne(optional = false)
@JoinColumn
@NonNull
@JsonIgnore
private Player player;
@NonNull
private Integer score;
@PrePersist
private void updatePlayerStat() {
player.getStat().incrementTotalGames();
player.getStat().addTotalScore(score);
}
GameStatistic
@Column(updatable = false)
@NonNull
private Integer durationMinutes;
@Temporal(TemporalType.TIMESTAMP)
@NonNull
private Date startedAt;
@ManyToOne(optional = false)
@JoinColumn
@NonNull
@JsonIgnore
private Player winner;
@OneToMany(mappedBy = "game")
private Set<GamePlayerScore> scores;
@PrePersist
private void update() {
winner.getStat().incrementTotalWins();
}
And how I store entries
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void prepossess() {
Date date = new Date();
Player john = new Player("john", date);
GameStatistic game = new GameStatistic(35, new Date(), john);
GamePlayerScore johnScore = new GamePlayerScore(game, john, 100);
playerRepository.save(player);
gameRepository.save(game);
scoreRepository.save(johnScore);
}
And how I read entry
@Transactional
public void insertAndRead() {
preprocess();
Player player = playerRepository.findByNickname("john");
System.out.println(player.getScores());
}