2012-10-02 4 views
9

Có ba bảng mô phỏng như ba tổ chức:JPA 3 chiều tham gia chú thích

@Entity 
@Table(name="event") 
public class Event { 
    public Long datetime; 
    public String name; 
    public Long processId; 
} 

@Entity 
@Table(name="process") 
public class Process { 
    public Long Id; 
    public Long sequence; 
    public Name name; 
} 

@Entity 
@Table(name="operation") 
public class Operation { 
    public Long Id; 
    public Long datetime; 
    public Long sequence; 
} 

Bất kỳ hồ sơ duy nhất độc đáo của quá trình hoạt động, trình tự thu được bằng các lệnh SQL mà có một 3-way tham gia hạn chế:

SELECT * 
FROM event e, process p, operation q 
WHERE e.processId = p.id 
    AND e.datetime = q.datetime 
    AND p.sequence = q.sequence 

để thực hiện điều đó trong JPA, tôi phải thực hiện một danh sách các hoạt động, mà sẽ được thu hẹp một cách rõ ràng xuống một hồ sơ duy nhất xuyên qua các p.sequence bình đẳng JQPL = q.sequence

@Entity 
@Table(name="event") 
public class Event { 
    public Long datetime; 
    public String name; 
    public Long processId; 
    @OneToOne 
    @JoinColumn(
    name = "processId", referencedColumnName="id", 
    insertable=false, updatable=false) 
    private Process process; 

    @OneToMany 
    @JoinColumn(
    name = "datetime", referencedColumnName="datetime", 
    insertable=false, updatable=false) 
    private List<Operation> operations; 
} 

Trường hợp JPQL xác định thứ 3 bắc cầu tham gia chế:

SELECT e FROM Event e 
INNER JOIN FETCH e.process p 
INNER JOIN FETCH e.operations q 
WHERE p.sequence = q.sequence 

Tuy nhiên, tôi muốn tất cả ba trở ngại để được mô hình bên trong tổ chức POJO. Không nên có cách nào để sử dụng chú thích JPA một mình để tham gia ba chiều? Khi pseudo-code thực thể sau đây minh họa:

@Entity 
@Table(name="event") 
public class Event { 
    public Long datetime; 
    public String name; 
    public Long processId; 
    @OneToOne 
    @JoinColumn(
    name = "processId", referencedColumnName="id", 
    insertable=false, updatable=false) 
    private Process process; 

    @OneToOne 
    @JoinColumn(
    name = "datetime", referencedColumnName="datetime", 
    insertable=false, updatable=false) 
    @JoinColumn(
    name = "process.sequence", referencedColumnName="sequence", 
    insertable=false, updatable=false) 
    private Operation operations; 
} 

Vì vậy, nó sẽ không cần thiết để xác định transitive-tham gia hạn chế trong JPQL

SELECT e FROM Event e 
INNER JOIN FETCH e.process p 
INNER JOIN FETCH e.operations q 

Làm thế nào để mô hình một transitive join sử dụng chú thích JPA?

+0

BTW, tôi đã bỏ qua các chú thích JAXB. Sự kiện phải hoàn toàn là thẻ gốc XML.Vì vậy, thực thể được mô hình hóa bằng cách sử dụng Event POJO. Thực thể Sự kiện được sử dụng trực tiếp dưới dạng XML DTO qua JAXB. Đó là để nói, bạn không nên đề nghị rằng tôi sử dụng một POJO như là gốc. –

+0

Tôi không chắc chắn 100% về vấn đề của bạn ... nếu bạn chỉ định mệnh đề ON của các phép nối, nó có giải quyết được vấn đề của bạn không? – slambeth

Trả lời

2

Dường như bạn đang cố tạo mô hình truy vấn thay vì dữ liệu của mình. Bạn nên lập mô hình dữ liệu của mình một cách chính xác, sau đó viết truy vấn của bạn.

Bạn dường như có

Event

  • quá trình
  • ManyToOne (ProcessID)

Process

  • sự kiện - OneToMany
  • hoạt động - OneToMany

Operation

  • quá trình - ManyToOne (sequence) (cái này là một chút kỳ quặc, như chuỗi không phải là Id, điều này nằm ngoài spec JPA, nhưng một số JPA cung cấp dịch vụ có thể hỗ trợ nó)

để truy vấn toàn bộ hoạt động cho một sự kiện, bạn có thể sử dụng,

Select o from Operation o join o.process p join p.events e where e.datetime = o.datetime 

Để có được tất cả các đối tượng lại sử dụng,

Select o, p, e from Operation o join o.process p join p.events e where e.datetime = o.datetime 

Nếu bạn thực sự cần để mô hình hóa các truy vấn như một mối quan hệ, điều này nằm ngoài spec JPA, nhưng một số nhà cung cấp JPA có thể hỗ trợ nó. Trong EclipseLink bạn có thể sử dụng một DescriptorCustomizer để cấu hình bất kỳ mối quan hệ nào để sử dụng bất kỳ tiêu chí biểu thức nào hoặc bạn sở hữu SQL.

+4

Hãy chấp nhận lời xin lỗi của tôi - nhưng bạn có thể tái cơ cấu câu trả lời của mình để trả lời câu hỏi của tôi thay vì tư vấn cho tôi cách xóa cuộc sống của những người mảnh vỡ đang ném tôi? Cảm ơn bạn. –

1

bạn pseudo-ánh xạ gần như là giải pháp đúng, bạn chỉ cần vào nhóm hai @JoinColumn s trong một @JoinColumns:

@OneToOne 
@JoinColumns({ 
    @JoinColumn(
    name = "datetime", referencedColumnName="datetime", 
    insertable=false, updatable=false), 
    @JoinColumn(
    name = "sequence", referencedColumnName="sequence", 
    insertable=false, updatable=false) 
}) 
private Operation operations;