2014-12-21 13 views
7

Tôi đang sử dụng EclipseLink với JavaDB và mỗi lần tôi cố gắng duy trì một thực thể người dùng mới. là null. Tôi biết nó là null - và nó phải là vì trường ID được tạo ra như là Identity trong cơ sở dữ liệu. Hoặc là tôi sai? Tôi đã thử thêm @GeneratedValue vào thực thể nhưng điều đó gây ra lỗi bất kể chiến lược thế hệ được sử dụng. Tôi cũng đã xem here, herehere nhưng những câu hỏi này dường như không liên quan đầy đủ đến vấn đề của tôi. Các ngoại lệ dưới đây luôn xảy ra khi có cuộc gọi đến EntityManager.persist (người dùng).Kiên trì một thực thể khi ID vô hiệu và được tạo tự động trong cơ sở dữ liệu

Tôi cũng đã thử xóa @NotNull và @GeneratedValue và, đủ kỳ quặc, nó đã vượt qua cuộc gọi vẫn tồn tại - nhưng chỉ để không thực hiện được cam kết. Theo như tôi có thể nói tôi đã có mọi thứ được thiết lập đúng. Vì vậy, câu hỏi đặt ra là: tại sao ứng dụng này không thêm người dùng mới và tôi cần phải làm gì để khắc phục sự cố?

tài thực thể:

@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 
} 

Tương ứng với Script này 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 
); 

tài Tạo Method (từ bộ điều khiển 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 lỗi (về cơ bản nói rằng trường ID là 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 lỗi (Bảng và Auto sản xuất cùng một ngoại lệ):

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

Trả lời

10

Không sử dụng @NotNull điểm traint trên @Id thuộc tính được tạo bằng chiến lược GenerationType.IDENTITY. Vấn đề là @NotNull và các ràng buộc khác JSR-303 được xác thực trước khi cam kết. Và số nhận dạng tự động không có sẵn cho đến sau khi cam kết hoàn tất.

Hãy thử điều này và không quan tâm về ID khởi tạo nữa:

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

Đây là giải pháp tốt hơn nhiều - tôi thực sự không quan tâm đến việc khởi tạo ID nữa !. Tôi nên thử nó trước khi đăng - nhưng nó hoạt động. Cảm ơn bạn @Lukas! –

0

Khi tôi đang sử dụng tự động tăng ở các định danh tôi làm như thế này:

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

Với Chú này cho id:

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

Welp đó đã làm nó. Nhưng wtf người đàn ông? Tại sao tôi phải đặt trường ID? Tôi có nghĩa là JPA nên tự động thiết lập nó. –

+0

Tôi không phải đặt trường ID - xem câu trả lời được chấp nhận. Bên cạnh đó, việc đặt ID thành 0 sẽ làm cho mọi thứ trở nên lộn xộn vì tôi bắt đầu số nhận dạng của tôi bằng không (xem SQL). -1 có thể làm việc nhưng tôi chưa bao giờ thử. –

Các vấn đề liên quan