开发者

JPA - Entity design problem

开发者 https://www.devze.com 2022-12-25 03:46 出处:网络
I am developing a Java Desktop Appli开发者_JAVA百科cation and using JPA for persistence. I have a problem mentioned below:

I am developing a Java Desktop Appli开发者_JAVA百科cation and using JPA for persistence. I have a problem mentioned below:

I have two entities:

  • Country
  • City

Country has the following attribute:

  • CountryName (PK)

City has the following attribute:

  • CityName

Now as there can be two cities with same name in two different countries, the primaryKey for City table in the datbase is a composite primary key composed of CityName and CountryName.

Now my question is How to implement the primary key of the City as an Entity in 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;
   }

Now as we know that the relationship from Country to City is OneToMany and to show this relationship in the above code, I have added a country variable in City class.

But then we have duplicate data(countryName) stored in two places in the City class' object: one in the country object and other in the cityPK object.

But on the other hand, both are necessary:

  • countryName in cityPK object is necessary because we implement composite primary keys in this way.

  • countryName in country object is necessary because it is the standard way of showing relashionship between objects.

How to get around this problem?


countryName in CityPK should be marked read-only using @Column(insertable = false, updatable = false) and both countryNames should be mapped to the same column (using name property):

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


IMO the proper way to deal with such issues would be to use a generated internal (typically Long) ID instead of a natural primary key - this eliminates the whole problem. Of course, this requires a modification of your DB schema, but from your post I assume that this is possible.

@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

精彩评论

暂无评论...
验证码 换一张
取 消