繁体   English   中英

休眠状态下何时会更新相关实体?

[英]When hibernate will update related entities?

我正在使用JPA春季数据,并且具有PlayerScore实体。 Player@OneToMany关系到Score (和@ManyToOneScorePlayer )。 我将Player保存到数据库中,但未指定相关分数。 之后,我将Score保存到数据库中,并将指向Player的链接传递给构造函数。 然后在同一个函数中,我读取了Player条目,但是它还没有指向Score条目的链接。
我的OneToMany关系中有FetchType.LAZY ,因此我需要在该函数中使用注释@Transactional 我还尝试保存玩家并在内部交易中得分(使用propogation=Propogation.REQUIRES_NEW ),并在外部交易中读取玩家条目,但这无济于事。 我也尝试添加CascadeType.ALL无效。 而且我从JpaRepository使用了flush()方法-也无济于事。
但是,如果我将使用一种控制器方法(使用spring MVC)保存播放器并得分,而又读入另一种方法,则播放器将具有指向得分的链接。
编辑 :添加代码,代码中的分数是GamePlayerScore 所有类都有@Getter批注@Getter@ToString

播放机

@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();
}

以及我如何存储条目

@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);
}

以及我如何阅读参赛作品

@Transactional
public void insertAndRead() {
    preprocess();
    Player player = playerRepository.findByNickname("john");
    System.out.println(player.getScores());
}

一旦清除了这些更改,保存分数将更新与数据库中玩家的关系。

但是,重装Player与已经包含了一个会话Player将弹出旧Player实例,而不与数据库中的数据进行更新。

因此,为了看到更改Player ,你需要刷新了会议,并删除Player从会话,然后重新装入。 另外,您也可以关闭会话。

您似乎试图通过单独的事务方法来实现这一目标。 原则上这应该可以工作,但是我几乎100%确信您有一个同时运行save和load方法的事务。 您可以为事务启用日志记录以便进一步调查: Spring hibernate事务日志记录

但是,您真正想做的可能是通过编写自定义设置器来使两个java对象保持同步。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM