JPA - проблема проектирования сущностей

Я разрабатываю Java-приложение для настольных компьютеров и использую JPA для постоянства. У меня есть проблема, упомянутая ниже:

У меня есть две сущности:

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

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

  • CountryName (PK)

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

  • Название города

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

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

   @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 и чтобы показать эту связь в приведенном выше коде, я добавил country переменная в City учебный класс.

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

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

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

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

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

2 ответа

countryName в CityPK должен быть помечен только для чтения с помощью @Column(insertable = false, updatable = false) и оба countryNames должны быть сопоставлены с тем же столбцом (используя 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;
   }

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

@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
}
Другие вопросы по тегам