2010-05-23 40 views
13

Về cơ bản tôi đã có giản đồ dưới đây và tôi đang chèn bản ghi nếu chúng không tồn tại. Tuy nhiên khi nói đến chèn một bản sao nó ném và lỗi như tôi mong đợi. Câu hỏi của tôi là liệu có một cách dễ dàng để làm cho Hibernate chỉ cần bỏ qua chèn mà có hiệu lực chèn bản sao?Hibernate constraint ConstraintViolationException. Có cách nào dễ dàng để bỏ qua các mục trùng lặp không?

CREATE TABLE IF NOT EXISTS `method` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `name` varchar(10) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `name` (`name`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; 


SEVERE: Duplicate entry 'GET' for key 'name' 
Exception in thread "pool-11-thread-4" org.hibernate.exception.ConstraintViolationException: could not insert: 

Trả lời

11

Câu hỏi của tôi là liệu có một cách dễ dàng để làm Hibernate để chỉ cần bỏ qua chèn mà sẽ ở bản sao tác chèn?

Làm cách nào Hibernate có thể biết rằng bản ghi có giá trị không duy nhất mà không thực sự chèn bản ghi?

Nếu bạn đang thực hiện chèn hàng loạt và không muốn khôi phục toàn bộ giao dịch và hủy phiên trong trường hợp ConstraintViolationException (đó là những gì bạn nên làm theo lý thuyết sau một ngoại lệ, hãy xem this threadprevious answer), đề xuất của tôi sẽ sử dụng API StatelessSession và để bắt số ConstraintViolationException.

+0

Vậy đó. StatelessSession đang thực hiện công việc. – Johanna

1

Cũng giống như Pascal đã nói, Hibernate sẽ không biết nếu nó là một bản sao cho đến khi nó đã thực sự được insrted.

Tôi đã gặp phải tình huống tương tự trước đây; một số chủ đề đã làm chèn cho DB, nhưng một số trong số đó sẽ là bản sao. Tất cả những gì tôi làm là bắt và phục hồi một cách duyên dáng khi một trong những ngoại lệ đó bị ném ra.

6

Hibernate không thể thực hiện việc này. Tuy nhiên bạn có thể tự mình làm điều đó. Về cơ bản có hai tùy chọn:

  1. Kiểm tra trùng lặp trước khi chèn; hoặc
  2. Bắt ConstraintViolationException và sau đó đảm bảo rằng vi phạm là do trùng lặp (vì có thể có các lý do khác, như trường trống).

Trước đây có bất lợi là bạn đang kiểm tra trùng lặp trên mỗi lần chèn khi khả năng thực sự có bản sao có thể thấp. Sau này sẽ nhanh hơn cho trường hợp thông thường, nơi không có trùng lặp xảy ra, nhưng có những bất lợi mà bạn cần phải kiểm tra các bản sao sau khi khuôn mặt. Khi một ConstraintViolationException được ném nó sẽ vô hiệu hóa phiên hiện tại; điều này có nghĩa là bạn sẽ cần phải tuôn ra trước khi thực hiện tìm kiếm một bản sao.

Kiểm tra trùng lặp trước khi chèn có lẽ là cách tiếp cận rõ ràng nhất trừ khi có vấn đề về hiệu suất chính mà bạn cần phải lo lắng. Hãy chắc chắn rằng bạn thực hiện tra cứu và chèn vào một giao dịch để đảm bảo rằng ai đó không thêm một bản sao giữa tra cứu và chèn, nếu không bạn sẽ nhận được một ConstraintViolationException.

1

Thay vì sử dụng createQuery() trong chế độ ngủ đông, hãy sử dụng createSQLQuery() và thử truy vấn như "giá trị phương thức REPLACE INTO (id) (123);"

1

Bạn có thể thử bắt ngoại lệ org.hibernate.exception.ConstraintViolationException và nuốt các ngoại lệ trong mã của bạn

Ví dụ:

try { 
    sessionFactory.getCurrentSession().saveOrUpdate(entity); 
} catch (ConstraintViolationException e) { 
    // Ignore the exception here by doing nothing 
} 
0

ngay cả khi bạn bắt ngoại lệ, có thể có những vấn đề khác

try{ 
     session.save(O); 
     session.getTransaction().commit(); 
    }catch (HibernateException e) { 
     System.out.println("you are carched ¤#%SD¤") ; 
    } 
0

Bạn có thể sử dụng chú thích @SqlInsert trên thực thể của mình, để thay đổi sử dụng sql hibernate để chèn vào trong Cơ sở dữ liệu, hibernate hiện tại phải sử dụng câu lệnh này

insert into method(name, id) values (?,?) 

Nếu bạn đang sử dụng mysql, bạn có thể sử dụng câu lệnh @SqlInsert để thay đổi sql chèn bằng cách sử dụng chèn bỏ qua tuyên bố mysql

@SQLInsert(sql = "insert ignore into method(name, id) values (?,?)") 

Tuy nhiên bạn sẽ nhận được các SQLs chèn bằng cách cho phép chương trình chế độ sql trong hibernate, vì thứ tự của các cột được tạo ra thông qua một số logic, và tài liệu của họ gợi ý theo cách này.

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