参照オブジェクト ItemVersion を持つエンティティ Company があり、永続レイヤーとして JPA (eclipselink) を使用しています。コードの抜粋を次に示します。
@Entity
public class Company{
private String instance;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "fk_item_version_id")
private ItemVersion itemVersion;
}
@Entity
public class ItemVersion{
private String comment;
...
}
Company オブジェクトを作成して永続化できます。また、新しいオブジェクトを見つけ、属性「インスタンス」を更新して永続化すると、すべて正常に動作します。参照されている ItemVersion オブジェクトの属性「comment」を変更すると、この変更はサーバー側に保存されません。
作成/更新テスト コードは次のようになります。
final EventBus eventBus = new SimpleEventBus();
final AftdRequestFactory requestFactory = GWT.create(AftdRequestFactory.class);
requestFactory.initialize(eventBus);
final CompanyRequest request = requestFactory.companyRequest();
final CompanyProxy newCompany = request.create(CompanyProxy.class);
newCompany.setInstance("1");
ItemVersionProxy newVersion = request.create(ItemVersionProxy.class);
newVersion.setComment("first comment");
newCompany.setItemVersion(newVersion);
request.persist().using(newCompany).fire(new Receiver<Void>() {
@Override
public void onSuccess(Void arg0) {
final CompanyRequest request2 = requestFactory.companyRequest();
Request<CompanyProxy> p = request2.findCompany(1L).with("itemVersion");
p.to(new Receiver<CompanyProxy>() {
@Override
public void onSuccess(CompanyProxy response) {
final CompanyRequest request3 = requestFactory.companyRequest();
final CompanyProxy editableCompany2 = request3.edit(response);
editableCompany2.setInstance("2");
editableCompany2.getItemVersion().setVersionNumber(2);
request3.persist().using(editableCompany2).fire(new Receiver<Void>() {
@Override
public void onSuccess(Void arg0) {
// persist company version
System.out.println("company updated");
ただし、「インスタンス」と「コメント」の更新はネットワークを介して行われますが (クライアントとサーバー間の Wireshark でチェックされます)、Company の persist メソッドでは、参照された ItemVersion オブジェクトとその「コメント」属性は「インスタンス」の間更新されません。 " が更新されたため、古いコメントが保存されます。
Company の persist メソッドは次のようになります。
public void persist() throws PersistenceException {
EntityManager em = emf.createEntityManager();
EntityTransaction tx = null;
try {
tx = em.getTransaction();
tx.begin();
Company existingEntity = findCompany(getId());
if (existingEntity == null) {
em.persist(this);
} else {
setId(existingEntity.getId());
em.merge(this);
}
tx.commit();
} catch (RuntimeException e) {
tx.rollback();
throw e;
}
単純な永続化では更新が保存されないため、検索による回避策と、検索結果によっては em.persist または em.merge が必要です。