我正在尝试使用表City
的复合主键,如果它没有被分配给Country
,那么它应该不存在(它应该是多对的...一个识别关系)。
我的问题首先是ChildId
(请参见嵌套类)在我初始化@GeneratedValue
之后null
Child
,如下所示:
List<City> cityList = new ArrayList<>();
City graz = new City(austria, "Graz");
// Runs without exceptions but graz.getCityId().getId() will be 'null'
cityList.add(graz);
cityList.add(new City(austria, "Wien"));
任何看起来因为它我得到org.hibernate.NonUniqueObjectException
例外:
完整的堆栈跟踪:
Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.mahlzeit.datamodel.address.City#com.mahlzeit.datamodel.address.City$CityId@8a62f66]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:138)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:204)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:189)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:642)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:635)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:631)
at com.mahlzeit.datamodel.HibernateTest.addAddressData(HibernateTest.java:63)
at com.mahlzeit.datamodel.HibernateTest.populateDatabase(HibernateTest.java:35)
at com.mahlzeit.datamodel.HibernateTest.main(HibernateTest.java:31)
我不知道我是否可以这样做。如果是的话,我该怎么做呢?
City.java
@Entity
public class City implements Serializable {
private static final long serialVersionUID = -4374113410767348574L;
@EmbeddedId
private CityId cityId;
private String cityName;
public City(Country country, String cityName) {
setCityId(new CityId(country));
this.cityName = cityName;
}
public String getCityName() {
return cityName;
}
public void setCityName(String countryName) {
this.cityName = countryName;
}
public CityId getCityId() {
return cityId;
}
public void setCityId(CityId cityId) {
this.cityId = cityId;
}
@Embeddable
public static class CityId implements Serializable{
private static final long serialVersionUID = -8561021314776406519L;
@GeneratedValue
private Long id;
private Country country;
public CityId(Country country) {
this.setCountry(country);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
}
}
Country.java
@Entity
public class Country implements Serializable {
private static final long serialVersionUID = -2060021861139912774L;
@Id
@GeneratedValue
private Long id;
@Column(unique=true)
private String countryCode;
public Country(String country_code) {
this.countryCode = country_code;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
答案 0 :(得分:1)
对于City
类,主键为CityId
,此类有2个属性 - id
&amp; country
。
请注意@GeneratedValue仅在该属性也使用@Id
注释时才有用,因此GeneratedValue
中id
属性的添加CityId
无效在类中,hibernate将忽略它。此外,您无法为此属性添加@Id
,因为此类代表@Embeddable
现在,在您的程序中,您正在设置CityId
,如下所示:
public City(Country country, String cityName) {
setCityId(new CityId(country));
this.cityName = cityName;
}
CityId
的构造函数是:
public CityId(Country country) {
this.setCountry(country);
}
所以最后你要创建两个同一个国家的城市:
City graz = new City(austria, "Graz");
new City(austria, "Wien");
另外,由于您没有为id
类的CityId
设置值,因此它始终为null
。所以city
对象graz
和&amp; wien
具有相同的主键,因为country
参考&amp; id
(在这种情况下为null)。
此外,您需要在您的实体之间进行适当的映射,请参阅此SO帖子以获取类似示例:
How to Represent Composite keys in Hibernate using Annotations?
来到id
的{{1}}属性,您必须明确设置,否则它将始终为CityId
。