2011-02-02 27 views
7

Tôi đang sử dụng JPA TopLink cần thiếtSQL Server 2008Tại sao JPA persist() không tạo ra ID chính tăng tự động?

Mục tiêu của tôi là để có được giá trị khóa chính auto-increment của dữ liệu có nghĩa là sẽ được chèn vào bảng. Tôi biết trong JDBC, có phương thức getInsertedId() giống như phương thức cung cấp cho bạn id của id chính tự động tăng (nhưng sau khi câu lệnh chèn được thực thi)

Trong JPA, tôi phát hiện ra @GenratedValue annotation.

@Entity 
@Table(name = "tableOne") 
public class TableOne implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "tableId") 
    private Integer tableId; 

Bây giờ nếu tôi chạy đoạn code dưới đây nó sẽ cho tôi tự động tăng lên id nhưng nó trả về NULL ...

EntityManager em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager(); 
EntityTransaction txn = em.getTransaction(); 
txn.begin(); 

TableOne parent = new TableOne(); 
em.persist(parent); //here I assume that id is pre-generated for me. 
System.out.println(parent.getTableId()); //this returns NULL :(
+0

Tôi có thể lấy id nếu tôi cam kết: em.getTransaction(). Cam kết() nhưng không có cách nào để lấy id đã tồn tại ??? hmm –

+0

Mã của bạn sẽ hoạt động như bạn mong đợi. Tôi đã thử nghiệm nó và tôi nhận được id trước khi cam kết hoặc nếu tôi sau đó rollback. Lạ thật là không. – Joel

+0

Nó có tạo ra sự khác biệt nào nếu tableId là một int chứ không phải là một số nguyên không? – Joel

Trả lời

2

Chúng tôi cũng đang sử dụng SQL Server 2008 và nó không bao giờ làm việc cho tôi vì vậy tôi luôn thực hiện truy vấn riêng biệt "SELECT @@IDENTY" để lấy id được chèn.

Lý do tôi tìm thấy trên mạng là id tự động (IDENTITY) được quản lý bởi cơ sở dữ liệu và không bao giờ được tìm nạp trong thực thể cho đến khi bạn không cam kết hàng hoặc truy xuất thông tin từ cơ sở dữ liệu theo cách thủ công.

+0

Bạn có nghĩa là vì SQL Server 2008, chúng tôi không thể sử dụng @ GeneratedValue.Sequence hoặc Bảng hoặc Identity ??? Tôi figured tôi đã phải tuôn ra đầu tiên (chèn cuộc gọi đến db để có được tạo ra id) nhưng mục tiêu của tôi là không có chèn cuộc gọi nếu tôi có thể nhận được id chính. –

+0

Bạn có thể đúng, tài liệu dường như không liệt kê SQL Server để hỗ trợ đối tượng SEQUENCE .... "Các đối tượng chuỗi sử dụng các đối tượng cơ sở dữ liệu đặc biệt để tạo các id. và Postgres. " http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Table_sequencing –

+0

đánh dấu là câu trả lời, SEQUENCE không được hỗ trợ bởi trình tự hmmm của SQL Server –

11

Vấn đề là bạn đang sử dụng tạo ID IDENTITY. Tạo ID IDITYITY không thể thực hiện preallocation vì chúng yêu cầu INSERT để tạo id. TABLE và SEQUENCE id hỗ trợ tạo preallocation, và tôi sẽ luôn luôn khuyên bạn nên sử dụng chúng, và không bao giờ sử dụng IDENTITY vì vấn đề này và vì hiệu suất.

Bạn có thể kích hoạt id được tạo khi sử dụng tạo ID IDITY bằng cách gọi flush().

+0

không hoạt động đối với tôi. Tôi đã thay đổi chú thích của mình trong lớp thực thể thành: '@Id @SequenceGenerator (name =" seq ", sequenceName =" seq ") @GeneratedValue (strategy = GenerationType).SEQUENCE, generator = "seq") ' –

+1

Sau đó, sau em.persist (myBean); int insertedId = myBean.getId(); GetId này() trả về null ... tôi có làm gì sai không? –

+1

Đó là vấn đề về thời gian. JPA không chèn dữ liệu khi bạn cố gắng lấy giá trị id. Bạn phải tuôn ra để làm cho anh ta bắt đầu thực hiện các sửa đổi trên cơ sở dữ liệu. Sau đó bạn có id. Tốt hơn là JPA sẽ thực hiện các sửa đổi trên db khi bạn gọi hàm getId(). –

6

chỉ đơn giản là làm điều này:

public void create(T entity) { 
    getEntityManager().persist(entity); 
    getEntityManager().flush(); 
    getEntityManager().refresh(entity); 
} 

Sau khi làm mới các đơn vị bạn có trường ID có giá trị thích hợp.

+3

Lý do để thêm 'flush()' là 'persist()' không được bảo đảm rõ ràng để tạo ra '@ GeneratedValue', nhưng nó phải được tạo ra tại hoặc trước' flush() '. Xem câu hỏi này: http://stackoverflow.com/questions/9087848/when-does-the-jpa-set-a-generatedvalue-id – Raedwald

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