重新保存修改过的对象时,java JPA merge()无法按预期工作
这是我为实体设置的:
@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
}
当我向电影列表中添加新的Actor
时,我能够成功地调用entityManager.merge()
。以下操作成功地保存了这些表
Movie movie = getMovieById(id);
movie.setActors(new Actor());
entityManager.merge(movie);
然后我想更新演员的名字,所以我要做的就是这样。我无法更新已保存/现有的参与者:
Movie movie = getMovieById(id);
movie.getActors().get(0).setName("New Name");
entityManager.merge(movie);
上面的方法不起作用,我可以看到对象在调试模式下被更新,但是当调用merge()
时,它不会更新数据库
我哪里做错了?我认为合并将更新,如果已经存在
# 1 楼答案
请参阅EntityManager接口的方法flush()的javadoc。您可以使用它将持久性上下文同步到基础数据库
如果FlushModeType被设置为
COMMIT
,那么底层数据库将在整个事务提交时更新。要解决这个问题,可以setFlushMode到AUTO (Default)
刷新每个查询。或者,您可以将代码的某些部分包装到NESTED
transaction中,只刷新这一部分。您还可以在当前事务中定期调用flush()方法:# 2 楼答案
整个管理者
merge()
操作用于将对分离对象所做的更改合并到持久性上下文中merge不会直接将对象更新到数据库中,它会将更改合并到持久性上下文(事务)中当
transaction
被提交时,或者如果持久性上下文被刷新,那么对象将在数据库中更新对你来说}才是必需的
merge
不是必需的,尽管它经常被误用。要更新一个对象,只需read
它,然后change
通过它的set
方法更新它的状态,然后提交transaction
。EntityManager
将找出所有已更改的内容,并更新数据库^只有当有persistence
对象的分离副本时,{只是在你的情况下,你没有做事务提交