gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-11-01 02:33:43 25 4
gpt4 key购买 nike

我正在编写一个网络服务来维护数据库。我正在尝试将 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com