当ID为null并在数据库中自动生成时,保持实体

时间:2014-12-21 21:23:56

标签: java jpa derby glassfish-4

我将EclipseLink与JavaDB一起使用,每当我尝试持久保存新用户实体时,我都会收到与新用户实体的ID字段为空的事实相关的错误。我知道它是空的 - 应该是因为ID字段是作为数据库中的标识生成的。还是我错了?我尝试将@GeneratedValue添加到实体,但无论使用何种生成策略,都会导致错误。我还查看了hereherehere,但这些问题似乎与我的问题无关。下面的例外总是在调用EntityManager.persist(用户)时发生。

我也尝试删除@NotNull和@GeneratedValue,奇怪的是,它已经超过了持久调用 - 但只是在提交失败。据我所知,我已经把一切都搞定了。所以问题是:为什么这个应用程序无法添加新用户,我需要做些什么来修复它?

用户实体:

 @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字段为空):

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)")

2 个答案:

答案 0 :(得分:12)

请勿对使用@NotNull策略生成的@Id属性使用GenerationType.IDENTITY约束。 问题是@NotNull并且在提交之前验证了其他JSR-303约束。 并且在提交完成之前,自动增量标识符不可用。

试试这个,不再关心ID初始化:

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

答案 1 :(得分:0)

当我在标识符处使用自动增量时,我喜欢这样:

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;
相关问题