web-dev-qa-db-ja.com

IDがnullの場合にエンティティを永続化し、データベースに自動的に生成されます

JavaDBでEclipseLinkを使用していますが、新しいユーザーエンティティを永続化しようとするたびに、新しいユーザーエンティティのIDフィールドがnullであるという事実に関連するエラーが発生します。私はそれがnullであることを知っています-そしてそれはIDフィールドがデータベースのIDとして生成されるためであるはずです。それとも私は間違っていますか? @GeneratedValueをエンティティに追加しようとしましたが、使用する生成戦略に関係なくエラーが発生します。 ここここここ も調べましたが、これらの質問は私の問題と完全には関連していないようです。以下の例外は、EntityManager.persist(user)の呼び出し時に常に発生します。

また、@ NotNullと@GeneratedValueを削除しようとしましたが、奇妙なことに、persist呼び出しを通過しましたが、コミットで失敗するだけでした。私が知る限り、私はすべてが正しく設定されています。したがって、問題は、このアプリケーションが新しいユーザーの追加に失敗する理由と、それを修正するために何をする必要があるのか​​ということです。

ユーザーエンティティ:

 @Entity(name = "User")
 @Table(name = "USERS")
 public class User implements Serializable {
     private static final long serialVersionUID = 1L;
     @Id
     @Basic(optional = false)
     @NotNull
     @Column(name = "IDENTIFIER", nullable = false,unique = true)
     private Long identifier;
     // class shortened for brevity
}

このSQLスクリプトに対応:

create table "USERSDBADMIN".USERS
(
        IDENTIFIER BIGINT not null primary key GENERATED ALWAYS AS IDENTITY 
            (START WITH 0, INCREMENT BY 1),
        USERNAME VARCHAR(50) not null,
        EMAIL VARCHAR(150) not null,
        LASTLOGIN DATE default NULL
);

ユーザー作成メソッド(JPAコントローラーから):

public void create(User user) throws PreexistingEntityException, RollbackFailureException, Exception {
    EntityManager em = null;
    try {
        utx.begin();
        em = getEntityManager();
        em.persist(user);
        utx.commit();
    } catch (Exception ex) {
        try {
            utx.rollback();
        } catch (Exception re) {
            throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
        }
        if (findUser(user.getIdentifier()) != null) {
            throw new PreexistingEntityException("User " + user + " already exists.", ex);
        }
        throw ex;
    } finally {
        if (em != null) {
            em.close();
        }
    }
}

GenerationStrategy.Identityエラー(基本的にIDフィールドがnullであると言っています):

ex = (javax.validation.ConstraintViolationException) javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'prePersist'. Please refer to embedded ConstraintViolations for details.

GenerationStrategy.Sequenceエラー(テーブルと自動は同じ例外を生成します):

ex = (org.Eclipse.persistence.exceptions.DatabaseException) Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.Eclipse.persistence.exceptions.DatabaseException. Internal Exception: Java.sql.SQLSyntaxErrorException: SEQUENCE 'SEQ_GEN_SEQUENCE' does not exist. Call: VALUES(NEXT VALUE FOR SEQ_GEN_SEQUENCE) Query: ValueReadQuery(sql="VALUES(NEXT VALUE FOR SEQ_GEN_SEQUENCE)")
11
Richard Barker

@NotNull戦略を使用して生成された@Id属性にGenerationType.IDENTITY制約を使用しないでください。問題は@NotNullであり、他のJSR-303制約はコミット前に検証されます。また、自動インクリメントされた識別子は、コミットが完了するまで使用できません。

これを試して、IDの初期化についてはもう気にしないでください。

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 @Column(name = "IDENTIFIER", nullable = false, unique = true)
 private Long identifier;
12
Lukas Risko

識別子で自動インクリメントを使用しているときは、次のようにします。

User user = new User();
user.setIdentifier((long) 0);// Assign 0 to ID for MSSQL/MySQL to properly auto_increment the primary key.
user.setUserName("some name");
...

IDのこの注釈を使用して:

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@NotNull
@Column(name = "ID")
private Long id;
0
NerosE