3

これは、データベースに既に存在する可能性のある一時オブジェクトの永続化に関する Hibernate の質問です。

データベースに既に存在する場合と存在しない場合があり、一意の列 (つまり、'unique=true' で注釈が付けられたビジネス主キー) を持つ一時的なオブジェクト (Id は null) が与えられます。エラーが発生するリスクなしに保存するにはどうすればよいですか:整合性制約違反: 一意制約またはインデックス違反

オブジェクトを永続化する前に、データベースの重複をチェックするメソッドを提供する必要がありますか? これは少しイライラします。

これは、2つの同一の一時オブジェクトを保存しようとするために実行するテストです...

ここに私のオブジェクトがあります:

@Entity
public class ArchivedLicence extends DomainObject implements Licence {
    private static final long serialVersionUID = 84973741L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;


    @Column (unique=true, nullable=false)
    private String md5Hash;

    @Override
    public boolean equals(Object o) {
        if(o instanceof ArchivedLicence) {
            return md5Hash.equals(((ArchivedLicence)o).md5Hash);
        }
        return super.equals(o);
    }
    ...

私のデータアクセスオブジェクトの保存方法は次のとおりです。

    @Transactional
    @Override
    public void saveOrUpdate(ArchivedLicence archivedLicence) {

        getCurrentSession().saveOrUpdate(archivedLicence);
        //getCurrentSession().save(archivedLicence);
    }

これが私のテストです:

        //Given the first ArchivedLicence
        ArchivedLicence archivedLicence1 = null;
        try {
            archivedLicence1 = new ArchivedLicence(licenceDao.getByName(internalLicenceName));
        } catch (IOException ex) {
            Logger.getLogger(OrderTest.class.getName()).log(Level.SEVERE, null, ex);
        }

        //When it is persisted
        archivedLicenceDao.saveOrUpdate(archivedLicence1);
        flush();

        //Then there should be one ArchivedLicence in the the database
        assertEquals(new Long(1), archivedLicenceDao.countAll());

        //When a second identical ArchiviedLicence is persisted
        ArchivedLicence archivedLicence2 = null;
        try {
            archivedLicence2 = new ArchivedLicence(licenceDao.getByName(internalLicenceName));
        } catch (IOException ex) {
            Logger.getLogger(OrderTest.class.getName()).log(Level.SEVERE, null, ex);
        }
        archivedLicenceDao.saveOrUpdate(archivedLicence2);
        flush();

        //Then there should still only be one ArchivedLicence in the database
        assertEquals(new Long(1), archivedLicenceDao.countAll());

助けていただければ幸いです、ありがとう、ジョン

4

1 に答える 1

1

残念ながら、データベースにクエリを実行してオブジェクトが存在するかどうかを確認し、存在する場合は更新し、存在しない場合は新しいオブジェクトを保存する必要があります。

saveOrUpdate はこの目的のためのものではありません。メモリ内のオブジェクトの ID をチェックし、ID が null の場合は save を呼び出し、id が null でない場合は update を呼び出します。

于 2012-02-24T14:32:50.850 に答える