JPA однонаправленное отношение один ко многим с использованием таблицы соединений - PullRequest
3 голосов
/ 08 июня 2011

Я хотел бы оценить JPA для существующего проекта. Модель базы данных и классы java существуют и в настоящее время отображаются через самогенерируемый код. Модель базы данных и классы Java не идеально подходят друг к другу, но настраиваемое отображение работает хорошо. Тем не менее, использование JPA в целом, кажется, стоит попробовать.

Как видите, я новичок в JPA и должен работать с конфигурацией xml. В настоящее время я работаю над однонаправленным отношением один ко многим, используя таблицу соединений (пожалуйста, не обсуждайте этот сценарий здесь).

A (one - relationship owner) <-> AB (JoinTable) <-> B (many)

Таблицы выглядят так

A
--
ID
BREF
...

B
--
ID
...

AB
--
A_BREF      (foreign key to a reference column in A which is NOT the id)
B_ID

Я бы хотел определить однонаправленное отношение один-ко-многим для класса А.

class A {

 private List<B> bs;

}

и сделал это так:

<one-to-many name="bs">
    <join-table name="ab">
        <join-column name="a_bref">
            <referenced-column-name name="bref" />
        </join-column>
        <inverse-join-column name="b_id">
            <referenced-column-name name="id" />
        </inverse-join-column>
    </join-table>
</one-to-many>

Хотя это не приводит к ошибке, она не работает. Проблема заключается в том, что таблица соединения не работает со столбцом идентификатора A. Запрос на выбор сущностей «B» работает со значением столбца A.ID вместо значения столбца A.BREF для выбора сущностей.

(Как) я могу заставить это отображение работать (я использую eclipselink 2.2.0)?

Спасибо за любые предложения!


EDIT:

Посмотрев на ссылку, представленную в ответе @ SJuan76, я немного изменил свое отображение на

<one-to-many name="bs">
    <join-table name="ab">
        <join-column name="a_bref" referenced-column-name="bref" />
        <inverse-join-column name="b_id" referenced-column-name="id" />
    </join-table>
</one-to-many>

Теперь это вызывает следующие ошибки (протестировано с eclipselink 2.1.0 и 2.2.0)

eclipselink 2.1.0

Описание исключения: параметр имя [bref] в выборе запроса критерий не соответствует ни одному параметру имя определено в запросе.

eclipselink 2.2.0

Описание исключения: ссылка имя столбца [bref] отображается на элемент [поле bs] не соответствуют действительному полю на ссылка на карту.

Между прочим - если я удаляю referenced-column-name="bref" из определения, я получаю то же исключение для referenced-column-name="id" для элемента inverse-join-column. Поэтому я сомневаюсь, что понял referenced-column-name правильно. Я использовал его, чтобы указать имя столбца базы данных таблиц, которые связаны с таблицей соединений. Это правильно?


РЕШЕНИЕ :

Последней ошибкой в ​​моем сценарии было то, что в моем классе не было определено поле BREF

class A {
    private long bref; // missing !
    private List<B> bs; 
}

и в моем orm.xml файле отображения для этого класса

<basic name="bref">
    <column name="bref" />
</basic>

Я не знал, что мне нужно определить используемые атрибуты сопоставления соединений referenced-column-name где-то в моих классах сопоставления (поскольку у меня также не было самой таблицы соединений или атрибутов name объединения-столбца / обратного- столбец соединения сопоставляется с классом или членами класса.)

Также мне помог совет, чтобы проверить проблему. Теперь я чувствую себя достаточно многословно в определении своего отображения, поскольку я перезаписываю все сопоставления по умолчанию (в верхнем регистре) значениями в нижнем регистре. Поскольку моя база данных не чувствительна к регистру, я буду использовать запись в верхнем регистре, если для соответствия стандартным значениям требуется специальное отображение.

+ 1 для всех!

Ответы [ 3 ]

1 голос
/ 08 июня 2011

Как правило, JPA требует, чтобы внешние ключи / столбцы соединения ссылались на первичный ключ / Id объекта. Но это должно работать с EclipseLink, поэтому, пожалуйста, включите генерируемый SQL, и, если он неправильный, зарегистрируйте ошибку.

Как определяется Id для A, это просто ID или ID и BREF?

Вы можете использовать DescriptorCustomizer, чтобы настроить ManyToManyMapping для отношения и установить правильное имя поля внешнего ключа.

1 голос
/ 09 июня 2011

Можете ли вы попытаться определить поле как "BREF" или использовать тот же самый точный случай, если вы определили его в сопоставлении атрибутов, или вы можете попробовать установить для свойства постоянства eclipselink.jpa.uppercase-column-names значение true. Это, вероятно, проблема с «id» при удалении referenced-column-name = «bref», поскольку для поля в сущности по умолчанию установлено значение «ID».

1 голос
/ 08 июня 2011
...