Однонаправленная связь "один ко многим" в JPA с использованием таблицы соединений

Я хотел бы оценить 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

Я хотел бы определить однонаправленную связь «один ко многим» для класса A.

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)?

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


РЕДАКТИРОВАТЬ:

Посмотрев ссылку, предоставленную в ответе @ 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" в элементе обратного соединения-столбца. Так что я сомневаюсь, что понял referenced-column-name правильно. Я использовал его, чтобы указать имя столбца базы данных таблиц, которые связаны с таблицей соединения. Это правильно?


РЕШЕНИЕ:

Последняя ошибка в моем szenario заключалась в том, что у меня не было поля 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 за всех!


person FrVaBe    schedule 08.06.2011    source источник


Ответы (2)


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

person Chris    schedule 09.06.2011
comment
Вы дали последний совет (если вы определили его в сопоставлении атрибутов), поэтому я приму ваш ответ. Добавил конкретное решение на мой вопрос. Спасибо! - person FrVaBe; 10.06.2011

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

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

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

person James    schedule 08.06.2011
comment
Идентификатор A - это просто идентификатор. Сгенерированный SQL действителен, но не использует A.BREF, как я уже упоминал. Я внес некоторые изменения и теперь получаю исключение. Пожалуйста, загляните в раздел редактирования моих вопросов. Пойду сейчас в Google за DescriptorCustomizer .... - person FrVaBe; 08.06.2011
comment
Ваше текущее исключение может быть проблемой. Имена столбцов по умолчанию написаны в верхнем регистре, поэтому попробуйте использовать все буквы в верхнем регистре в именах столбцов. - person James; 09.06.2011