7

私はJavaデスクトップアプリケーションを開発しており、JPAを永続化に使用しています。以下の問題があります。

私は2つのエンティティを持っています:

国には次の属性があります。

  • 国名 (PK)

City には次の属性があります。

  • 都市名

2 つの異なる国に同じ​​名前の 2 つの都市が存在する可能性があるため、データベース内の City テーブルの primaryKey は、CityNameとで構成される複合主キーCountryNameです。

今私の質問は、主キーをJavaで実装する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からへの関係がわかっているのでCityOneToMany上記のコードでこの関係を示すために、クラスにcountry変数を追加しました。City

しかし、クラスのオブジェクトcountryName内の 2 つの場所に重複した data( ) が格納されています。1 つはオブジェクト内、もう1 つはオブジェクト内です。CitycountrycityPK

しかし一方で、両方が必要です。

  • countryNamecityPKこのように複合主キーを実装するため、in object が必要です。

  • countryNamein countryobject は、オブジェクト間の関係を示す標準的な方法であるため、必要です。

この問題を回避するにはどうすればよいですか?

4

2 に答える 2

7

countryNameinCityPKを使用して読み取り専用としてマークし@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;
   }
于 2010-04-01T19:17:52.837 に答える
3

このような問題に対処する IMO の適切な方法Longは、自然な主キーの代わりに生成された内部 (通常は ) ID を使用することです。これにより、問題全体が解消されます。もちろん、これにはDBスキーマの変更が必要ですが、あなたの投稿から、これは可能であると思います.

@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
}
于 2010-04-02T08:35:55.753 に答える