Альтернативный подход к однонаправленному отображению @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.

Когда я осмотрелся, похоже, что это известная ошибка: https://issues.apache.org/jira/browse/OPENJPA-1607 .

Я что-то пропустил или это сопоставление выглядит нормально? Насколько я вижу, чтобы обойти эту проблему, у меня есть 2 подхода:

  1. Сделайте сопоставление двунаправленным. Однако, как я читал, в двунаправленном сопоставлении OneToMany владельцем является ManyToOne. Таким образом, в этом случае таблица заказов будет владельцем, что на самом деле не так с точки зрения дизайна. Заказов не будет, без клиента.
  2. Добавьте однонаправленное сопоставление ManyToOne из заказов в таблицу клиентов, и для любых запросов для всех заказов для конкретного клиента просто запросите таблицу заказов с идентификатором клиента. Конечно, это будет означать несколько запросов вместо одного запроса.

Итак, мой вопрос о дизайне: какой подход вы считаете более чистым и эффективным? Есть ли вообще лучший другой подход? Есть ли какая-либо производительность или какие-либо другие преимущества использования однонаправленного сопоставления вместо двунаправленного сопоставления? Я искал вокруг, но не мог найти много статей об этом. Не уверен, что пропустил. Если преимуществ не так много, то мне может быть лучше с подходом 1.

Прошу прощения, если я что-то пропустил. Любые указатели приветствуются. Спасибо за ваше время заранее.

спасибо,

Алиса


person Alice    schedule 11.07.2015    source источник


Ответы (1)


Получил эту работу, опубликовав ответ, так как он может помочь кому-то еще.

Оказывается, однонаправленное сопоставление «один ко многим» работает в OpenJPA, пока вы указываете таблицу соединений. Я тоже видел проблему, указанную в ошибке: https://issues.apache.org/jira/browse/OPENJPA-1607 . Однако, как только я добавил таблицу Join, все заработало как по маслу. Конечно, это означает, что мне придется добавить дополнительную таблицу, но это значительно сократит количество кода и ошибок при обновлениях и удалениях. Как только мы доберемся до представления, я посмотрю, как оно работает. Но пока это все для меня. Ниже приведен фрагмент:

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;
    ....
}
person Alice    schedule 16.07.2015