12

这是我为实体设置的:

@Entity
@Getter
@Setter
@Table(name = "movies", schema = "public")
public class Movie {
    @Id
    @Column(name = "id")
    private UUID movieId;

    @OneToMany(mappedBy = "actor", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private Set<Actors> actors = new HashSet<>();

    //Getters and setters
    }
}
@Entity
@Getter
@Setter
@Table(name = "actors_movies", schema = "public")
public class ActorMovie {
    @EmbeddedId
    private ActorId id;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("movieId")
    @JoinColumn(name = "id_movie_movie")
    private Movie movie;

    //Getters and setters below
}

entityManager.merge()当我将新电影添加Actor到电影列表时,我能够成功调用。以下成功持久化了表。

Movie movie = getMovieById(id);
movie.setActors(new Actor());
entityManager.merge(movie);

然后我想更新演员的名字,所以我要做的就是这个。我无法更新已经持久化/现有的 Actor:

Movie movie = getMovieById(id);
movie.getActors().get(0).setName("New Name");
entityManager.merge(movie);

以上不起作用,我可以看到在调试模式下正在更新的对象但是当merge()被调用时它不会更新数据库。

我哪里错了?我认为如果已经存在,合并会更新。

4

2 回答 2

8

实体管理器。merge()操作用于将对分离对象所做的更改合并到持久性上下文中。合并不直接将对象更新到数据库中,它会将更改合并到持久性上下文(事务)中。

transaction提交时,或者如果持久性上下文被刷新,那么对象将在数据库中更新。

For youmerge不是必需的,尽管它经常被误用。要更新一个对象,你只需要read它,然后change通过它的set方法更新它的状态,然后提交transaction. 将EntityManager找出所有已更改的内容并更新数据库。merge仅当您拥有persistence对象的分离副本时才需要。

就您而言,您没有提交交易。

entityManager.getTransaction().commit();
于 2020-06-09T05:12:48.280 回答
1

请参阅EntityManager接口的方法flush()的 javadoc 。您可以使用它将持久性上下文同步到底层数据库

如果FlushModeType设置为,COMMIT则在整个事务提交时更新底层数据库。要解决此问题,您可以setFlushModeAUTO (Default)刷新每个查询。或者您可以将部分代码包装到NESTED 事务中以仅刷新这部分。您还可以在当前事务中定期调用flush()方法:

entityManager.flush();
entityManager.clear();
于 2020-06-11T22:47:24.367 回答