我正在寫一個web服務來維護一個數據庫。我正嘗試將JPA(EclipseLink)用於實體類。但是,數據庫使用自然主鍵,因此由於外鍵約束,ID字段的更新可能會失敗。我們的DBA提供了一個函數來更新ID字段,這些字段將使用更新的ID創建一個新的父記錄,更新子記錄以指向新的父項並刪除舊的父項。JPA - 使用可插入/可更新
如果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不合適的情況?
對此的任何建議,非常感謝。
主鍵由用戶輸入,如果有拼寫錯誤,我們需要讓他們糾正它。我不指望它經常發生,但它是可能的。 – sdoca 2010-07-22 15:21:04
@sdoca:我明白了。但仍然:) – 2010-07-22 15:52:02
我同意,我習慣於使用序列的ID,但我沒有任何控制在這個模式中使用自然主鍵。 – sdoca 2010-07-22 16:01:59