繁体   English   中英

JAVA JPA更新相关实体

[英]JAVA JPA updating the related entities

我在更新相关实体时遇到问题。

让我从一个简单的例子开始。 假设我有一个User 1:1 Profile关系。

如何更新(替换)属于User的Profile实体?

我尝试了以下失败的尝试(OneToOne关系都有CascadeType = ALL属性)

em.getTransaction().begin();

1.User.setProfile(Profile)
....
2.User.setProfile(Profile)
Profile.setUser(User)
.....
3.em.remove(User.getProfile())
User.setProfile(Profile)
Profile.setUser(User)

em.getTransaction().commit();

我对JPA完全感到困惑,有一些有用的示例,但它们与更新实体无关(仅更新单个值,提高薪水等)。

我希望所建议的方法在1:N关系的情况下也能适用。

我总是做em.merge(user); 更新实体后。 如果您有适当的级联选项,这也会更新所有相关的实体。

现在,我知道(听说)该实体应该在事务结束时更新数据库本身,但是我更喜欢直接打电话。 坦率地说,我发现整个“自动更新实体”模式在现实世界开发中更多的是问题而不是优势。

这取决于您想做什么。 如果User和Profile是真正一对一的,那么用一个不同的Profile对象替换整个Profile对象的整个想法有点多余。 如果使用的框架在整个操作中都保留了持久性上下文,则可以仅更新 Profile对象中的值并进行刷新,因为级联会导致创建新对象有些混乱。

但是,如果您的框架没有保留Persistence Context,那么您将拥有已被修改的分离实体,您必须使用em.merge() 获取原始实体( em.find )并复制在IMO中,如果给定正确使用JPA的框架,这将很繁琐,容易出错且不必要。 最好在持久性上下文中修改对象,然后让“自动更新实体”来完成任务(显然,我非常喜欢)。 这需要一点时间来适应,但是一旦您习惯了,就永远不会回头。

无论如何,在调用em.flush()时,所有更改都将写到JDBC连接中,并且在事务完成时将提交连接中的未决更改。

如何更新(替换)属于用户的Profile实体?

由于关联是双向的,因此您必须管理UserProfile之间的链接的两端。 因此,“更改”用户的个人资料将需要以下内容:

User user = em.find(User.class, key);

Profile profile = new Profile();
...
user.setProfile(profile);
profile.setUser(user);

em.getTransaction().commit(); 

使用我使用的JPA实现,已经对上述代码执行了以下查询:

INSERT INTO CPROFILE (ID) VALUES (?)
    bind => [2]
UPDATE CUSER SET CPROFILE_ID = ? WHERE (ID = ?)
    bind => [2, 1]

我删除了CascadeType ALL,一切都按预期运行,代码如下


......................... CPROFILE
@Entity
public class CProfile {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Key id;
        private String phone;

    @OneToOne(mappedBy="profile")
    private CUser User;

......................... CUSER @Entity public class CUser { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Key id; private String email;

@OneToMany(mappedBy="user")
private List<CPossibility> Possibilities = new ArrayList<CPossibility>();

@OneToOne 
@JoinColumn(name="cprofile_id") 
private CProfile profile;   

......................... CREATE ... CUser User = em.find(CUser.class, UserId_); ...
em.getTransaction().begin(); try { Profile_.setUser(User); User.setProfile(Profile_);

        em.persist(Profile_);

        em.getTransaction().commit();
    }
    catch(Exception e){GAEHelper.getLogger().warning("Exception:"+e.getMessage()+" "+e.getCause());}        
    finally {
        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }
    }

    em.close();

    return true;
}

......................... UPDATE
... CUser User = em.find(CUser.class, UserId_); ... em.getTransaction().begin(); try { em.remove(User.getProfile());

        Profile_.setUser(User);             
        User.setProfile(Profile_);

        em.persist(Profile_);
        em.getTransaction().commit();
    }

多谢你们 !

卡萨巴

暂无
暂无

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

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