【问题标题】:The entity is not updated on entity listener @PostPersist (Spring data jpa)实体未在实体侦听器 @PostPersist 上更新(Spring 数据 jpa)
【发布时间】:2018-08-23 00:47:12
【问题描述】:

我有下一张 ER 图
我想在每次保存 Score 实体时更新 PlayerStat 实体。所以我尝试使用@PostPersist注解。当我保存 Score 实体时,调用该注释的函数,但更改,我在此函数中所做的不会持续存在。我的实现如下。所有实体类都有构造函数的 lombok 注释。
Player

@Id
@GeneratedValue(generator = "custom-uuid")
@GenericGenerator(name = "custom-uuid", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;

@Temporal(TemporalType.DATE)
@Getter
@NonNull
private Date createdAt;

@Column(unique = true)
@Getter
@Setter
@NonNull
private String nickname;

@OneToMany(mappedBy = "winner")
@Getter
@NonNull
private Set<Game> gamesWon;

@Getter
@OneToOne(cascade = CascadeType.PERSIST, optional = false)
@JoinColumn
private PlayerStat stat;

@OneToMany(mappedBy = "player")
@Getter
@NonNull
private Set<Score> scores;

public Player(String nickname, Date createdAt) {
    this.nickname = nickname;
    this.createdAt = createdAt;
    stat = new PlayerStat(0, 0, 0, this);
}

游戏

@Id
@GeneratedValue(generator = "custom-uuid")
@GenericGenerator(name = "custom-uuid", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;

@Getter
@NonNull
@Column(updatable = false)
private Integer durationMinutes;

@Temporal(TemporalType.DATE)
@Getter
@NonNull
private Date dateStarted;

@ManyToOne(optional = false)
@JoinColumn
@Getter
@NonNull
private Player winner;

@OneToMany(mappedBy = "game")
@Getter
private Set<Score> scores;

@PostPersist
private void update(){
    System.out.println("On game post persist");
    winner.getStat().incrementTotalWins();
}

玩家统计

@Id
@GeneratedValue(generator = "custom-uuid")
@GenericGenerator(name = "custom-uuid", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;

@Getter
@Setter
@NonNull
private Integer totalScore;

@Getter
@NonNull
private Integer totalWins;

@Getter
@NonNull
private Integer totalGames;

@Getter
@OneToOne(mappedBy = "stat", optional = false)
@NonNull
private Player player;

public void incrementTotalWins() {
    totalWins++;
}

public void incrementTotalGames() {
    totalGames++;
}

得分

@Id
@GeneratedValue(generator = "custom-uuid")
@GenericGenerator(name = "custom-uuid", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;


@ManyToOne(optional = false)
@JoinColumn(name = "game_id")
@Getter
@NonNull
private Game game;

@ManyToOne(optional = false)
@JoinColumn
@Getter
@NonNull
private Player player;

@Getter
@NonNull
private Integer score;



@PostPersist
void updatePlayerStat(){
    System.out.println("On score post persist");
    player.getStat().incrementTotalGames();
    player.getStat().setTotalScore(player.getStat().getTotalScore() + score);
    System.out.println(player);
}

所以,我尝试保存单个 PlayerGame 与该玩家,以及 Score 与该游戏和玩家。这两个函数都调用了@PostPersist 注释。然后在另一个请求中我读了这个播放器。应用了 Game 函数中的更改,但未应用 Score 函数中的更改。但是如果我像这样单独请求(它与实体侦听器无关)

score.getPlayer().getStat().incrementTotalGames();
score.getPlayer().getStat().incrementTotalWins();
score.getPlayer().getStat().setTotalScore(100);
scoreRepository.save(score);

将应用所有更改。
我还尝试使用单独的 EntityListener 类并进入该类存储库,保存修改后的对象,但这也不起作用。我尝试在每个关系中添加CascadeType.ALL,仍然没有变化。那么我应该怎么做才能自动更新 PlayerStat?

【问题讨论】:

    标签: java database hibernate jpa spring-data-jpa


    【解决方案1】:

    如果您使用@PostPersist,信息将在持久化后更新,因此您将没有数据库中的信息,因此您应该在将结果保存到数据库之前在服务层进行此增量,您也可以尝试:

    1- @PrePersist 因为 PrePersist Executed before 实体管理器持久化操作实际执行或级联。此调用与持久操作同步。

    2-@PreUpdate 因为 PreUpdate数据库UPDATE操作之前执行。

    【讨论】:

      【解决方案2】:

      在我看来你想要的是 @PrePersist

      并且您确实想在 Game 中向玩家添加 级联,并且

      【讨论】:

      • 是的,使用 @PrePersist 似乎工作正常。谢谢你。现在它无需额外的级联即可工作。
      【解决方案3】:

      @PostPersist - 和其他回调方法- 有局限性,不能更新实体状态

      【讨论】:

        【解决方案4】:

        根据我的经验(在 WildFly 中),您必须手动刷新保存语句,否则更改会丢失。另请参阅 JPA 规范中的注释(JPA 2.2 第 3.5.3 节)。调用与事务划分相关的 post persist 方法的确切时间似乎并没有非常精确地定义。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-14
          • 2014-02-10
          相关资源
          最近更新 更多