1

Hibernate ver.でJPA 2を使用しています。4.1.7.Final としての JPA 実装。明確にするために、Spring フレームワーク v. 3.1.2.RELEASE も使用しています。そして、ここに私の問題があります。

User エンティティを追加/更新するメソッドを作成しました。

@Override
@Transactional
public void saveUser(UserForm userForm) {
    User user;

    if (userForm.getId() == null) { // new user
        user = new User();
        user.setCreationDate(new Date());
        entityManager.persist(user); // !!!
    } else {
        user = entityManager.find(User.class, userForm.getId());
    }

    user.setFirstName(userForm.getFirstName());
    user.setLastName(userForm.getLastName());
    user.setMiddleName(userForm.getMiddleName());

    user.setEmail(userForm.getEmail());

    user.setRole(entityManager.find(Role.class, 1));//TODO

    user.setLogin(userForm.getLogin());
    user.setPassword(userForm.getPassword1());

    entityManager.flush();
}

ユーザーの追加をテストしています (userForm.getId() == null)。そして、上記のコードは機能せず、エラーが発生します:

javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Column 'first_name' cannot be null
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1306)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:989)
...

しかし。flush() がすべて正常に動作する前に、persist() への呼び出しを最後に移動すると、次のようになります。

@Override
@Transactional
public void saveUser(UserForm userForm) {
    User user;

    if (userForm.getId() == null) { // new user
        user = new User();
        user.setCreationDate(new Date());
    } else {
        user = entityManager.find(User.class, userForm.getId());
    }

    user.setFirstName(userForm.getFirstName());
    user.setLastName(userForm.getLastName());
    user.setMiddleName(userForm.getMiddleName());

    user.setEmail(userForm.getEmail());

    user.setRole(entityManager.find(Role.class, 1));//TODO

    user.setLogin(userForm.getLogin());
    user.setPassword(userForm.getPassword1());

    entityManager.persist(user);// !!!
    entityManager.flush();
}

何が起こるかは、最初の(問題)ケースで、ユーザーオブジェクトデータを保存しようとする場合に発生すると思いますが、実際の保存はflush()中に実行されますが(upd。間違っています。persist(で正確にSQL挿入を発行しようとします) ) 電話)。このように考えさせられるのは、デバッグしようとしたときに、正しい creation_date を内部のどこかに挿入しようとしていることがわかりましたが、他の値は null です。

しかし、私が数年前に取り組んでいた他のプロジェクトでは、これは問題なく機能したことを誓いますが、その後、MySQL の代わりに Oracle を使用し (これが理由ではないと思います)、古いバージョンのフレームワークを使用しました。

ここで何が問題になる可能性がありますか?これに影響を与えるHibernateの設定オプションがあるのでしょうか?

または、これは正しい動作であり、JPA API に対する私の誤解ですか?

アップデート。私は使用しています

@Id
@GeneratedValue
@Column(columnDefinition="INT")
private int id;

ユーザー エントリの id フィールド。mysqlのauto_incrementキーに適した生成戦略= AUTOを意味すると思います。

4

2 に答える 2

1

それは正しい振る舞いです。最初に persist() を呼び出した時点で、ユーザーの firstName は null です。この時点の後、フラッシュの前に最初の名前を設定したとしても、JPA/Hibernate で準備されたコマンドは次のようになります。

永続化の時点で、ユーザー オブジェクトの状態は、user@version1 user@version1 オブジェクトからユーザー値 (id、creationdate、null、null ..) に挿入します。

新しいユーザー バージョンが存在するようになりました user@version2

フラッシュ時には、

保留中の挿入/更新を確認します。すべてのオブジェクトを、最後の永続化時のバージョン 1 にします。

フラッシュは DB で物理的な挿入操作を行う場合と行わない場合がありますが、オブジェクトは正しい状態になります。つまり、永続化されていない変更が失われることに注意してください。

以前は休止状態 3 で正常に動作していた可能性があり、休止状態 4 に移行したときに動作しなくなった場合でも心配しないでください。

于 2012-10-09T08:04:32.583 に答える
1

ユーザーの名を null ( user.setFirstName(userForm.getFirstName());)に設定するuserForm.getFirstName()と、null が返され、エラーで次のように表示されますColumn 'first_name' cannot be null

null を返す理由を確認するかuserForm.getFirstName()、現在のエンティティ構成では許可されていないため、ユーザーの名を null にすることを許可する必要があります。

多分あなたは私たちに User エンティティを見せてもらえますか?

于 2012-10-08T20:22:23.680 に答える