2010-04-01 4 views
7

Java Desktop Application을 개발하고 지속성을 위해 JPA를 사용하고 있습니다. 나는 문제가 아래에 언급 한 :JPA - 엔티티 디자인 문제

나는 두 기관이 있습니다

  • 나라를
  • 도시
  • 에게

나라 다음과 같은 속성이 있습니다

  • COUNTRYNAME (PK)

시는 다음과 같은 속성이 있습니다

  • CityName이를
이제

두 개의 서로 다른 나라에서 같은 이름을 가진 두 도시가 될 수 있듯이, DATBASE 도시 테이블에 대한 기본 키가 구성된 복합 기본 키입니다 CityNameCountryName.

지금 내 질문은 우리가 City- Country의 관계가 OneToMany 것을 알고 이제 자바

@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; 
    } 

EntityCity의 기본 키를 구현하기 위해이 보여 어떻게 관계 위의 코드에서 City 클래스에 country 변수를 추가했습니다. cityPK 객체의 country 객체의 하나 및 기타 :

는하지만 우리는 City 클래스의 객체에 두 장소에 저장된 중복 데이터 (countryName)가 있습니다.

그러나 다른 한편으로

이 모두 필요하다 : 우리는이 방법으로 복합 기본 키를 구현하기 때문에

  • countryNamecityPK의 객체가 필요하다.

  • countryNamecountry 개체간에 relationship을 표시하는 표준 방법이기 때문에 개체가 필요합니다.

이 문제를 해결하는 방법은 무엇입니까? (name 속성을 사용하여) CityPK에서

답변

7

countryName은 읽기 전용 @Column(insertable = false, updatable = false)를 사용하여 표시해야 두 countryName의이 같은 컬럼에 매핑해야합니다 IMO

@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; 
    } 
+0

이 유형의 문제를 처리하는 표준 방법입니까? 이 문제는 JPA에서 흔히 발생합니까? –

+0

@Yatendra : 예, 표준 방법입니다 (대리 키를 사용하지 않는 경우 피터가 제안한 것처럼). – axtavt

3

것 같은 문제를 다루는 적절한 방법 자연스러운 기본 키 대신 생성 된 내부 ID (일반적으로 Long)를 사용하면 전체적인 문제가 제거됩니다. 물론 이것은 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 
} 
+0

그렇다면 평등을 위해 equals 메서드에서'id'를 사용할 수 없다고 생각합니다. 옳은? –

+0

@Yatendra 왜 안 되니? 같은 이름이지만 다른 나라의 두 도시는 서로 다른 ID를 가져야합니다. 동일한 국가의 동일한 도시를 테이블에 두 번 삽입하지 않도록하십시오. 이것은 DB 트리거 또는 Hibernate 인터셉터에 의해 시행 될 수 있습니다. –

+0

'id'가 데이터베이스에 의해 생성되기 때문에'equals()'에'id'를 사용할 수 없습니다. 그리고 개체가 지속될 때까지 사용할 수 없습니다. 개빈 킹 (Gavin King)의 '최대 절전 모드로 자바 지속성 (Java Persistence with Hibernate)'을 참조하십시오. 비즈니스 키와 대리 키에 대한 설명을 참조하십시오. – Ram