Слияние сущности JPA возвращает старые значения - PullRequest
4 голосов
/ 21 сентября 2011

У меня есть 2 сущности JPA, которые имеют двунаправленную связь между ними.

@Entity
public class A {

     @ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE})
     B b;

     // ...
}

и

@Entity
public class B {

     @OneToMany(mappedBy="b",cascade={CascadeType.PERSIST, CascadeType.MERGE})
     Set<A> as = new HashSet<A>();

     // ...
}

Теперь я обновляю некоторые значения полей отдельного A, который также имеетотношения с некоторыми Bs и наоборот и слияние обратно с помощью

public String save(A a) {
    A returnedA = em.merge(a);
}

returnedA теперь имеют значения A до их обновления.Я полагаю, что

  FINEST: Merge clone with references A@a7caa3be
  FINEST: Register the existing object B@cacf2dfb
  FINEST: Register the existing object A@a7caa3be
  FINEST: Register the existing object A@3f2584b8

указывает на то, что ссылка As в B (которая все еще имеет старые значения) ответственна за перезапись новых?

У кого-нибудь есть подсказка, какне допустить этого?

Любая идея очень ценится!

Заранее спасибо.

1 Ответ

1 голос
/ 21 сентября 2011

Дирк, у меня была похожая проблема, и решение (возможно, я не правильно использовал API) было интенсивным.Eclipselink поддерживает кэш объектов, и если они не обновляются (объединяются / сохраняются), часто база данных отражает изменения, но каскадные объекты не обновляются (особенно родительские).

(я объявил A какзапись, объединяющая несколько B) Сущности:

public class A
{
  @OneToMany(cascade = CascadeType.ALL)
  Collection b;
}

public class B
{
  @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}) //I don't want to cascade a persist operation as that might make another A object)
  A a;
}

В случае, описанном выше, обходной путь:

public void saveB(B b) //"Child relationship"
{
  A a = b.getA();//do null checks as needed and get a reference to the parent
  a.getBs().add(b); //I've had the collection be null
  //Persistence here
  entityInstance.merge(a); // or persist this will cascade and use b
}

public void saveA(A a)
{
  //Persistence
  entityInstance.merge(a) // or persist
}

То, что вы делаете здесь - это физическое каскадное слияние по цепочке сверху,Поддерживать раздражает, но это решает проблему.В качестве альтернативы вы можете справиться с этим, проверив, отсоединен ли он, и обновите / замените, но я обнаружил, что работать с ним менее желательно и раздражающе.

Если у кого-то есть лучший ответ относительно правильной настройкиЯ был бы счастлив услышать это.Прямо сейчас я применил этот подход для своих реляционных сущностей, и поддерживать его определенно раздражает.

Желаю удачи, я бы хотел услышать лучшее решение.

...