2015-07-11 39 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; 
    .... 
}