JPA - Проблема проектирования объекта

Я разрабатываю Настольное приложение Java и использую JPA для персистентности. Мне упомянули проблему ниже:

У меня есть два объекта:

  • Страна
  • Город

Страна имеет следующий атрибут:

  • CountryName (PK)

Город имеет следующий атрибут:

  • CityName

Теперь как может быть два города с тем же именем в двух разных странах, primaryKey для таблицы City в datbase является составным первичным ключом, состоявшим из CityName и CountryName.

Теперь мой вопрос состоит в том, Как реализовать первичный ключ City как Entity в Java

   @Entity
   public class Country implements Serializable {
       private String countryName;

       @Id
       public String getCountryName() {
           return this.countryName;
       }
   }

  @Entity
  public class City implements Serializable {
           private CityPK cityPK;
           private Country country;

           @EmbeddedId
           public CityPK getCityPK() {
               return this.cityPK;
           }
   }


   @Embeddable
   public class CityPK implements Serializable {
       public String cityName;
       public String countryName;
   }

Теперь, поскольку мы знаем что отношения от Country кому: City OneToMany и показать эти отношения в вышеупомянутом коде, я добавил a country переменная в City класс.

Но затем у нас есть дублирующиеся данные (countryName) сохраненный в двух местах в City объект класса: один в country возразите и другой в cityPK объект.

Но с другой стороны, оба необходимы:

  • countryName в cityPK объект необходим, потому что мы реализуем составные первичные ключи таким образом.

  • countryName в country объект необходим, потому что это - стандартный способ показать relashionship между объектами.

Как обойти эту проблему?

7
задан Yatendra Goel 1 April 2010 в 18:38
поделиться

2 ответа

ИМО, правильным способом решения таких проблем было бы использование сгенерированного внутреннего (обычно Long ) идентификатора вместо естественного первичного ключа - это устраняет всю проблему. Конечно, это требует модификации вашей схемы БД, но из вашего сообщения я предполагаю, что это возможно.

@Entity
public class City implements Serializable {
    private Long id;

    private String name;
    private Country country;

    @Id
    @GeneratedValue
    @Column(name = "CITY_ID")
    public Long getId() {
        return this.id;
    }
    private void setId(Long id) {
        this.id = id;
    }

    // more getters, setters and annotations
}
3
ответ дан 7 December 2019 в 01:19
поделиться

countryName в CityPK следует пометить как доступный только для чтения с помощью @Column (insertable = false, updatable = false ) и оба countryName должны быть сопоставлены с одним и тем же столбцом (с использованием свойства name ):

  @Entity
  public class City implements Serializable {
           @EmbeddedId
           private CityPK cityPK;

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


   @Embeddable
   public class CityPK implements Serializable {
       public String cityName;

       @Column(name = "countryName", insertable = false, updatable = false)
       public String countryName;
   }
7
ответ дан 7 December 2019 в 01:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: