0

重複の可能性:
Spring + Hibernate:同じ識別子値を持つ別のオブジェクトがすでにセッションに関連付けられています

私はJavaBeanとして次のオブジェクト(簡略化)を持っています:

public class Person {
  private Integer id;
  private City cityOfBirth;
  private City city;
  // ...
}

そして、私の春のフォームでは、次のように、両方の都市を選択するために2つの選択コンボがあります。

<form:form method="post" action="" commandName="person">
City of birth: <form:select path="cityOfBirth" items="${ cities }" itemValue="id" />
City: <form:select path="city" items="${ cities }" itemValue="id" />
...
</form:form>

Cityクラスの私のPropertyEditorは、CityDaoのgetを呼び出すだけで、次のようになります。

@Component
public class CityDaoImpl implements CityDao {
  private @Autowired HibernateTemplate hibernateTemplate;

  public City get (Integer id) {
    return (City) hibernateTemplate.get(City.class, id);
  }
}

そして、私のPersonDaoは、インスタンスを保存するためにこれを行います。

public void save (Person person) {
  hibernateTemplate.saveOrUpdate (person);
}

2つの異なる都市を持つ人を保存しようとすると、すべて正常に機能しますが、同じ都市を選択すると、次のエラーが発生します。

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.project.si.models.common.City#90]

他の投稿でこれが発生するのは、Hibernate SessionがpropertyEditorが呼び出されたときに取得された以前のCityを認識しているcityDao.get(id)ためです。したがって、どこかでmerge()を使用することになっていますが、これをどこに適用すればよいかわかりません。 。

4

1 に答える 1

1

この問題は、saveOrUpdate()操作をからPersonにカスケードするという事実が原因で発生し、更新するオブジェクトと同じIDを持つオブジェクトがすでにに関連付けられている場合は失敗します。Cityupdate()Session

cityこの問題の最善の解決策は、とからカスケードオプションを削除することだと思いますcityOfBirth

ユーザーが既存の都市のリストからを選択する必要がある限り、からへCityの変更をカスケードする必要がないため、ここではカスケードは意味がありません。PersonCity

merge()または、次の代わりに使用できますsaveOrUpdate()

public void save (Person person) {
    hibernateTemplate.merge(person); 
} 
于 2012-09-06T15:51:22.977 に答える