2015-07-11 68 views
0

你好數據庫專家,備選設計方法,@OneToMany單向映射OpenJPA中不工作

考慮以下表:

CREATE TABLE customers (
    id INTEGER NOT NULL PRIMARY KEY, 
    name VARCHAR(100) NOT NULL, 
    order_id INTEGER NOT NULL, 
    CONSTRAINT customers_ibfk_1 FOREIGN KEY (order_id) REFERENCES orders (id) ON DELETE CASCADE, 
); 

CREATE TABLE orders (
    id INTEGER NOT NULL PRIMARY KEY, 
    date VARCHAR(100) NOT NULL, 
    ... 
); 

由於大多數我的查詢,並在應用程序需要只需要訪問訂單與客戶相關聯,我決定從客戶到訂單進行單向一對多映射,因爲可以將多個訂單與客戶相關聯。我安排的實體類如下:

public class Customer implements Serializable { 
... 
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    @JoinColumn(name = "id", referencedColumnName = "order_id") 
    private Set<Order> orders; 
.... 
} 

它編譯罰款使用JPA 2.0和OpenJPA 2.4.0。然而,拋出以下異常在運行時:

... 
nested exception is <openjpa-2.4.0-r422266:1674604 fatal general error> org.apache.openjpa.persistence.PersistenceException: The transaction has been rolled back. See the nested exceptions for details on the errors that occurred.] with root cause 
org.apache.openjpa.persistence.ArgumentException: You cannot join on column "customers.order_id". It is not managed by a mapping that supports joins. 

當我環顧四周,看起來是已知的bug:https://issues.apache.org/jira/browse/OPENJPA-1607

我在這裏錯過了什麼,或者這個映射看起來好嗎?爲了解決這個問題,我可以看到兩種方法:

  1. 使映射成爲雙向的。然而,據我所知,在OneToMany雙向映射中,ManyToOne是所有者。所以在這種情況下,訂單表將成爲所有者,從設計的角度來看,情況並非如此。沒有客戶就沒有訂單。
  2. 添加從訂單到客戶表的ManyToOne單向映射,以及針對特定客戶的所有訂單的任何查詢,只需使用客戶ID查詢訂單表即可。當然,這意味着多個查詢應該是單個查詢。

所以我的設計問題是:您認爲哪種方法更清潔,更高效?是否有更好的不同方法?使用單向映射而不是雙向映射有任何性能或其他好處嗎?我環顧四周,但找不到很多文章。不知道我是否錯過了它。如果沒有太多的好處,那麼我可能會更好的方法1.

我很抱歉,如果我錯過了什麼。任何指針都非常感謝。提前感謝您的時間。

感謝,

愛麗絲

回答

0

得到這個工作,發佈的答案,因爲它可能幫助了另外一個人。

只要您指定了一個聯接表,就可以在OpenJPA中執行一對多單向映射。我也看到了該錯誤中指定的問題:https://issues.apache.org/jira/browse/OPENJPA-1607。但是,一旦我添加了一個聯接表,它就像一個魅力。當然,這意味着我將不得不添加一個額外的表格,但它會大大減少更新和刪除的代碼量和錯誤數量。一旦我們達到了表現,我會看到它的表現。但現在,這是我的。以下是摘錄:

public class Customer implements Serializable { 
    ... 
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    @JoinTable(name = "customers_orders", 
     joinColumns = { @JoinColumn(name = "customer_id", referencedColumnName = "id") }, 
     inverseJoinColumns = { @JoinColumn(name = "order_id", referencedColumnName = "id") }) 
    private Set<Order> orders; 
    .... 
}