当前位置:  开发笔记 > 编程语言 > 正文

JPA - 使用可插入/可更新

如何解决《JPA-使用可插入/可更新》经验,为你挑选了1个好方法。

我正在编写一个Web服务来维护数据库.我正在尝试将JPA(EclipseLink)用于实体类.但是,数据库使用自然主键,因此由于外键约束,ID字段的更新可能会失败.我们的DBA提供了一个更新ID字段的功能,这些ID字段将创建具有更新ID的新父记录,更新子记录以指向新父记录并删除旧父记录.

如果ID字段可以"正常"更新,我会遇到这样的情况:

@Entity
@Table(name = "PARENT")
public class Parent implements Serializable
{
    private static final long serialVersionUID = 1L;
    private String parent;
    private String attribute;
    private Set childs;

    public Parent()
    {
    }

    @Id
    @Column(name = "PARENT")
    public String getParent()
    {
        return this.parent;
    }

    public void setParent(String parent)
    {
        this.parent = parent;
    }

    @Column(name = "ATTRIBUTE")
    public String getAttribute()
    {
        return this.attribute;
    }

    public void setAttribute(String attribute)
    {
        this.attribute = attribute;
    }

    @OneToMany(mappedBy = "parentBean")
    public Set getChilds()
    {
        return this.childs;
    }

    public void setChilds(Set childs)
    {
        this.childs = childs;
    }
}

@Entity
@Table(name = "CHILD")
public class Child implements Serializable
{
    private static final long serialVersionUID = 1L;
    private String child;
    private String attribute;
    private Parent parentBean;

    public Child()
    {
    }

    @Id
    @Column(name = "CHILD")
    public String getChild()
    {
        return this.child;
    }

    public void setChild(String child)
    {
        this.child = child;
    }

    @Column(name = "ATTRIBUTE")
    public String getAttribute()
    {
        return this.attribute;
    }

    public void setAttribute(String attribute)
    {
        this.attribute = attribute;
    }

    @ManyToOne
    @JoinColumn(name = "PARENT")
    public Parent getParent()
    {
        return this.parent;
    }

    public void setParent(Parent parent)
    {
        this.parent = parent;
    }
}

我还有一个GenericServiceBean类,它带有一个调用函数的方法:

@Stateless
public class GenericServiceBean implements GenericService
{
    @PersistenceContext(unitName = "PersistenceUnit")
    EntityManager em;

    public GenericServiceBean()
    {
        // empty
    }

    @Override
    public  T create(T t)
    {
        em.persist(t);
        return t;
    }

    @Override
    public  void delete(T t)
    {
        t = em.merge(t);
        em.remove(t);
    }

    @Override
    public  T update(T t)
    {
        return em.merge(t);
    }

    @Override
    public  T find(Class type, Object id)
    {
        return em.find(type, id);
    }

    . . . 

    @Override
    public String executeStoredFunctionWithNamedArguments(String functionName,
            LinkedHashMap namedArguments)
    {
        Session session = JpaHelper.getEntityManager(em).getServerSession();

        StoredFunctionCall functionCall = new StoredFunctionCall();
        functionCall.setProcedureName(functionName);        
        functionCall.setResult("RESULT", String.class);

        for (String key : namedArguments.keySet())
        {
            functionCall.addNamedArgumentValue(key, namedArguments.get(key));
        }

        ValueReadQuery query = new ValueReadQuery();
        query.setCall(functionCall);

        String status = (String)session.executeQuery(query);

        return status;
    }
}

如果我将ID字段设置为不可编辑:

    @Id
    @Column(name = "PARENT", udpatable=false)
    public String getParent()
    {
        return this.parent;
    }

并且parent.setParent(newParent)这仍然会更新实体对象中的ID吗?这对任何子实体有何影响?它们是否也会更新(或不更新)?

我不知道如何处理的另一个场景是我需要更新ID和另一个属性.我是否应该调用更新(并提交)数据库中的ID的函数,然后通过普通的set*方法调用设置ID和属性,然后持久化上下文只提交属性更改?

也许这是JPA不合适的情况?

对此有任何建议非常感谢.



1> Pascal Thive..:

如果我将ID字段设置为不可编辑(...)并且调用parent.setParent(newParent)将仍然更新实体对象中的ID?这对任何子实体有何影响?它们是否也会更新(或不更新)?

updatable=false表示无论您在对象级别执行什么操作,该列都不会成为SQL UPDATE语句的一部分,因此Id不应更新该列.而且我也很想说儿童实体不应该受到影响,特别是因为你没有任何级联.

我不知道如何处理的另一个场景是我需要更新ID和另一个属性(...)

好吧,我的理解是你无论如何都要调用这个函数,所以我先调用它.

也许这是JPA不合适的情况?

我不确定原始SQL会更好地处理您的情况.实际上,如果可能的话,改变主键的整个想法听起来很奇怪.

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有