Сопоставление импортированных из БД стран для адресации объекта с помощью JPA - PullRequest
1 голос
/ 17 ноября 2009

Я запустил некоторый сценарий DDL, чтобы настроить полную таблицу стран в моей базе данных. Столбец первичного ключа таблицы стран содержит соответствующий код ISO для каждой страны.

В моем проекте JPA у меня есть сущность User, имеющая встроенную сущность Address, и эта сущность Address имеет ссылку на страну. Взаимоотношения между пользователем и адресом, кажется, не проблема для меня, но отношения между адресом и страной Я попытался отобразить это как отношение ManyToOne, так как многие адреса могут совместно использовать страну.

Проблема в том, что я пометил переменную-член iso класса Country с помощью Id -> Теперь JPA / Hibernate жалуется на то, что не установил id страны вручную. Но в этом случае идентификатор уже задан и установлен, так как я импортировал данные один раз, и код ISO уникален, и с помощью схемы db он объявлен как первичный ключ. В этом особом случае нет необходимости в обновлениях или вставках в таблицу стран - информация должна быть только для чтения!

Есть идеи, что делать, чтобы я мог использовать таблицу стран без изменений?

1 Ответ

0 голосов
/ 17 ноября 2009

В вашем вопросе отсутствуют некоторые детали, поэтому следующее требует много догадок :-)

Ваш Country класс должен выглядеть примерно так:

@Entity
@Immutable
@Table(name="countries")
public class Country {
  @Id
  private String isoCode;
  // all other attributes, getters / setters, etc...
}

@Immutable - это расширение Hibernate по стандарту JPA; Вы не должны помещать его в сущность, но наличие этого приведет к немного лучшей производительности. Имейте в виду, что действительно сделает Country неизменным - вы не сможете создавать / обновлять / удалять страны через ваше приложение. Вы также можете настроить кеш для вашей сущности Country, если она используется достаточно часто.

Ваш Address будет иметь следующую привязку к стране:

@ManyToOne
@JoinColumn(name="country_iso_code")
private Country country;

Обратите внимание на отсутствие атрибутов "каскад" - они вам не нужны. Последнее важное замечание: вам нужно получить или загрузить экземпляр Country, чтобы установить его по адресу:

Country country = (Country) session.load(Country.class, isoCode);
// OR
Country country = (Country) session.get(Country.class, isoCode);

address.setCountry(country);
...
session.saveOrUpdate(address);

Первая строка выше не попадет в базу данных; используйте его, если вы знаете, что страна с таким кодом ISO существует. Вторая форма будет попадать в базу данных (или в кеш, если настроено) и возвращать NULL, если страны с таким кодом не существует.

...