java - JPA - 使用可插入/可更新

标签 java jpa orm eclipselink

我正在编写一个网络服务来维护数据库。我正在尝试将 JPA (EclipseLink) 用于实体类。但是,数据库使用自然主键,因此 ID 字段的更新可能会由于外键约束而失败。我们的 DBA 提供了更新 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<Child> 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<Child> getChilds()
    {
        return this.childs;
    }

    public void setChilds(Set<Child> 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> T create(T t)
    {
        em.persist(t);
        return t;
    }

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

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

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

    . . . 

    @Override
    public String executeStoredFunctionWithNamedArguments(String functionName,
            LinkedHashMap<String, String> 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不合适的情况?

非常感谢对此的任何建议。

最佳答案

If I set the ID fields to be not editable (...) and call parent.setParent(newParent) will this still update the ID in the entity object? How does this affect any child entities? Will they also be updated (or not)?

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

Another scenario I don't know how to deal with is where I need to update both the ID and another attribute (...)

嗯,我的理解是无论如何你都必须调用函数,所以我会先调用它。

Perhaps this is a situation where JPA is not appropriate?

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

关于java - JPA - 使用可插入/可更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3301967/

相关文章:

java - Gson:@Expose 与 @SerializedName

java - JPA 实体类给出 2 个 @GenerateValue 字段的错误

php - 将此复杂查询转换为 ORM 或 Laravel 查询生成器

java - 如何通过 JPA 注释将不同的国家/州代码映射到基本实体?

java - 如何在 Eclipse 中为标准 Java API 创建自定义警告

java - hibernate3 maven 插件 :make hbm2java generate hibernate annotations instead of ejb3 annotations

java - 如何为DataStore设置jndi.properties?

MySQL 性能和 Memcache

java - 业务层是否应该将持久化对象返回给UI层?

java - 嵌套 if、else if,不带括号