简体   繁体   English

重新保存修改后的 object 时,JPA 合并()无法按预期工作

[英]JPA merge() doesn't work as expected when resaving a modified object

This is my set up for the entity:这是我为实体设置的:

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

I am able to successfully call entityManager.merge() when I add a new Actor to the list of movie.当我将新Actor添加到电影列表时,我能够成功调用entityManager.merge() The following successfully persists the tables.以下成功持久化了表。

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

Then I want to update the actor name so what I do is this.然后我想更新演员的名字,所以我要做的就是这个。 I am NOT able to update an already persisted/existing Actor:我无法更新已经持久化/现有的 Actor:

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

The above doesn't work, I can see the object being updated in debug mode but when merge() is called it doesn't update the database.以上不起作用,我可以看到 object 正在调试模式下更新,但是当调用merge()时它不会更新数据库。

Where am I going wrong?我哪里错了? I thought merge would update if already existing.我认为如果已经存在,合并会更新。

The EntityManager.实体管理器。 merge() operation is used to merge the changes made to a detached object into the persistence context. merge()操作用于将对分离的 object 所做的更改合并到持久性上下文中。 merge does not directly update the object into the database, it merges the changes into the persistence context (transaction). merge 不会直接将 object 更新到数据库中,它会将更改合并到持久化上下文(事务)中。

When the transaction is committed, or if the persistence context is flushed, then the object will be updated in the database.transaction提交时,或者如果持久性上下文被刷新,那么 object 将在数据库中更新。

For you merge is not required, although it is frequently misused.对于你来说, merge不是必需的,尽管它经常被误用。 To update an object you simply need to read it, then change its state through its set methods, then commit the transaction .要更新 object,您只需read它,然后通过其set方法change其 state,然后提交transaction The EntityManager will figure out everything that has been changed and update the database. EntityManager将找出所有已更改的内容并更新数据库。 merge is only required when you have a detached copy of a persistence object.仅当您拥有persistence object 的分离副本时才需要merge

Just in your case you arent doing commit of transaction.就您而言,您没有提交交易。

entityManager.getTransaction().commit();

See the javadoc of the EntityManager interface's method flush() .请参阅EntityManager接口的方法flush()的 javadoc。 You can use it to synchronize the persistence context to the underlying database .您可以使用它将持久性上下文同步到底层数据库

If the FlushModeType is set to COMMIT then underlying database is updated at the time of whole transaction commit.如果FlushModeType设置为COMMIT ,则在整个事务提交时更新底层数据库。 To resolve this you can setFlushMode to AUTO (Default) to flush each query.要解决此问题,您可以将FlushMode 设置AUTO (Default)以刷新每个查询。 Or you can wrap some part of your code into NESTED transaction to flush only this part.或者您可以将部分代码包装到NESTED 事务中以仅刷新这部分。 Also you can periodically invoke the flush() method inside current transaction:您还可以在当前事务中定期调用flush()方法:

entityManager.flush();
entityManager.clear();

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

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