2015-03-21 12 views
5

Tôi có một bảng khách hàng, mỗi khách hàng thuộc về một công ty, công ty muốn số khách hàng của họ bắt đầu bằng 0 và tăng khi họ thêm khách hàng và khi công tyB thêm khách hàng, số lượng khách hàng của công tyA không bị ảnh hưởng. CustomerId nội bộ có thể là bất kỳ số nào, customerNumber phải được tăng thêm khoảng trống trong ngữ cảnh của companyId (với khoảng cách không có nghĩa là 0,1,2,3,4, nếu 2 bị xóa, nó đã biến mất, chèn tiếp theo sẽ là 5 chứ không phải 2)Làm thế nào để tạo ra một máy khách customerNumber cho mỗi công ty trong Hibernate

Example: 
    companyId customerNumber customerId 
    0   0    0 
    0   1    1 
    0   2    2 
    0   3    3 
    0   4    4 
    0   5    5 
    1   0    6 
    1   1    7 
    1   2    8 

tôi đã tự hỏi nếu có một cách tốt hơn để làm điều đó vì mở một giao dịch, tìm max CUSTOMERNUMBER, chèn một mục bằng cách sử dụng tối đa + 1 như CUSTOMERNUMBER và đóng cửa giao dịch

Có một số loại chú thích tôi có thể sử dụng nơi tôi có thể chỉ định các tiêu chí để tạo ra một customerNumber không? Số khách hàng tiếp theo phải là số cao nhất có sẵn trong công ty đó. (Tôi có khoảng 20 thực thể khác có các yêu cầu tương tự như người đọc có thể đọc được dựa trên ngày tháng và comapnyId và tôi muốn tạo ra các trường kiểu khách hàng kiểu gõ là chứng minh ngu ngốc nhất có thể, tôi không muốn nhớ để làm điều đó mỗi khi tôi vẫn tồn tại một thực thể mới)

Cái gì như:

@SequenceGenerator(uniqueOver="companyId,customerNumber",strategy=GenerationType.AUTO) 
private Long customerNumber; 

Các giải pháp phải phù ACID kể từ khi tôi đang làm việc với chứng khoán và dữ liệu tài chính.

Cập nhật: Tôi đã đổi tên id thành customerId và customerId thành customerNumber để tránh nhầm lẫn.

Cập nhật: Khi tôi có nghĩa là không có khoảng trống, tôi có nghĩa là khách hàng phải là 0,1,2,3,4,5,6,7,8,9 - nếu tôi xóa số 4, nó đã biến mất mãi mãi và chèn tiếp theo sẽ là 10, trừ khi tôi tạo ra một công ty mới, sau đó khách hàng đầu tiên của họ nên bắt đầu từ 0.

cập nhật: tôi đang sử dụng mùa xuân với chế độ ngủ đông, do đó chú thích @PrePersist không hoạt động cho tôi. Nếu @PrePersist được đề xuất như là một giải pháp, sau đó nó cần phải làm việc dưới mùa xuân, vì vậy một câu trả lời cho câu hỏi của Simon sẽ là cần thiết: Enable @PrePersist and @PreUpdate in Spring

trả lời đề nghị mà tôi không chắc chắn về:

@Entity 
@Table(name = "Customer") 
public class Customer { 

    @Table(name = "CustomerNumber") 
    @Entity(name = "sequenceIdentifier") 
    public static class CustomerNumberSequenceIdentifier { 

     @Id 
     @GenericGenerator(name = "sequence", strategy = "sequence", parameters = { 
       @org.hibernate.annotations.Parameter(name = "sequenceName", value = "sequence"), 
       @org.hibernate.annotations.Parameter(name = "allocationSize", value = "1"), 
     }) 
     @GeneratedValue(generator = "sequence", strategy=GenerationType.SEQUENCE) 
     private Long id; 

    } 


    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long customerId; 

    @ManyToOne 
    private Company company; 

    @GeneratedValue(generator = "sequenceIdentifier", strategy=GenerationType.TABLE) 
    private Long customerNumber 

} 

Trả lời

1

Nếu bạn sử dụng chế độ ngủ đông; Ví dụ Query

Query query = session.createQuery("insert into customer (company_id, customer_id)" +"(select :company_id, IFNULL(max(customer_id),1)+1 from customer where company_id = :company_id)");

//set the company_id here 

    int result = query.executeUpdate(); 

Lưu ý: IFNULL là một MYSQL cụ thể cú pháp

Tôi đề nghị giữ lĩnh vực công ty id auto_increment trong một bảng công ty chủ riêng biệt.

2

trong khi tôi không thể nói chuyện với phía hibernate của vật (xin lỗi), bạn có thể thực hiện điều này với một bảng trong mysql chừng nào nó sử dụng động cơ MyISAM, với cấu trúc bảng sau:

create table ai_test (
    company_id integer, 
    customer_number integer auto_increment, 
    primary key (company_id, customer_number) 
) engine=MyISAM; 

Dưới đây là af iddle cho thấy rằng trong hành động: http://sqlfiddle.com/#!9/45e78/1

Xin lỗi tôi không thể dịch này thành ngủ đông cho bạn - không bao giờ sử dụng nó, nhưng điều này có thể là một điểm khởi đầu.

chỉnh sửa
từ INNO là cần thiết, bạn có thể sử dụng bảng này và kích hoạt:

create table ai_test (
    company_id integer, 
    customer_number integer, 
    primary key (company_id, customer_number) 
) engine=InnoDB; 


create trigger inno_composite_ai_ok before insert on ai_test 
for each row 
begin 
    set new.customer_number =  
     (select ifnull((select max(customer_number)+1 
         from ai_test 
          where 
         company_id=new.company_id),1)); 
end// 

Đây là một fiddle mẫu cho bạn: http://sqlfiddle.com/#!9/fffd0/14

chỉnh sửa
Một hơn cập nhật để bao gồm yêu cầu của một cột PK

create table ai_test (
    company_id integer, 
    customer_no integer, 
    customer_id integer primary key auto_increment 

) engine=InnoDB; 

create trigger inno_composite_ai_ok before insert on ai_test 
for each row 
begin 
    set new.customer_no =  
     (select ifnull((select max(customer_no)+1 
         from ai_test 
          where 
         company_id=new.company_id),1)); 
end// 

fiddle here

Lưu ý bạn có thể (và có lẽ nên) đặt một hạn chế duy nhất trên toàn company_d/CUSTOMER_NO

1

Bạn đang tìm kiếm tạo chuỗi số mà không cần phải ghi ddl để tạo số thứ tự mới cho mỗi bảng. Làm điều này với một bảng số thứ tự riêng biệt và tạo một lựa chọn cho giao dịch cập nhật để khóa cả hai bảng để chèn. Hibernate thực hiện điều này với các bảng nâng cao.

Dưới đây là một ví dụ khá tốt: http://vladmihalcea.com/hibernate-identity-sequence-and-table-sequence-generator/

Cuộn xuống TABLE (SEQUENCE) phần, đó là một bảng của giải pháp số thứ tự.

Trong ví dụ, chỉ cần chỉ định tên khách hàng làm tên chuỗi để nhận đúng trình tự.

Chi phí trên tạo ra một chuỗi thứ tự cho mỗi công ty mới và khóa bảng cho mọi khách hàng mới.

+0

Lớp TableSequenceIdentifier của bạn, tôi giả định rằng, trong trường hợp của tôi, lớp Khách hàng? Làm thế nào tôi có thể nhận được số lượng khách hàng cho mỗi công ty bằng cách sử dụng ví dụ trình tự bảng? –

+0

Lớp định danh thứ tự bảng là một bảng riêng biệt chỉ lưu trữ các giá trị chuỗi cho khách hàng của bạn. Nó sẽ giữ companyid và giá trị chuỗi tiếp theo cho công ty đó. Hibernate cung cấp các bảng nâng cao để thực hiện lựa chọn cho chiến lược cập nhật/cập nhật để gói giao dịch chèn của bạn. Điều này cung cấp cho bạn một cập nhật chuỗi an toàn khóa. Chèn bảng khách hàng của bạn bây giờ sẽ dựa vào lớp trình định danh thứ tự bảng. – user1442498

+0

Tôi không hoàn toàn theo dõi ... Tôi đã cập nhật câu hỏi của mình, customerId là trường tự động gia tăng, mỗi Công ty có thể có nhiều khách hàng và mỗi customerNumber phải tăng mỗi công ty. Lớp CustomerNumberSequenceIdentifier của tôi có chính xác cho những gì tôi đang cố gắng làm không và làm cách nào để đưa nó vào CustomerNumber để tôi có thể nhận được số khách hàng tăng cho mỗi công ty theo ví dụ của tôi ở trên? Các ví dụ tôi tìm thấy là tất cả chỉ hiển thị như thế nào mà số thứ tự bảng được tạo ra trình tự. Hãy chỉnh sửa mô hình ngủ đông trong câu hỏi của tôi và điền vào các khoảng trống. –

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