Я пытаюсь использовать составной первичный ключ для таблицы City
, которая не должна существовать, если она не назначена на Country
(предполагается, к-одному идентифицирующая связь).Композитный первичный ключ ведет к org.hibernate.NonUniqueObjectException
Моя проблема заключается в первую очередь, что 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
исключение :
Полный StackTrace:
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#[email protected]]
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;
}
}
Ну да, но как бы я сгенерировал 'CityId.id'? Это просто * имеет *, чтобы как-то автогенерировать, как '@ Id'. Как мне это сделать? Я не хочу, чтобы я устанавливал его явно, потому что мне пришлось бы искать себя, если это значение все еще доступно или нет. Должен быть способ использования автоматически сгенерированного (или автоматического прироста) значения. – displayname
@StefanFalk, мой ответ о том, почему вы получаете эту проблему, и исправить это, вы должны явно указать этот идентификатор, автоматическое создание не будет работать , Но я вижу, что у вас уже есть отдельный вопрос: http://stackoverflow.com/questions/29976363/hibernate-generatedvalue-in-embedded-always-null, а steve и дать ответ, попробовали ли вы эту опцию. – Chaitanya
Нет, я не был на машине, но я попробую это через несколько часов, когда я туда доберусь. Я приму ваш ответ здесь. Если хотите, я могу сообщить, могу ли я решить проблему id и как это сделать. :) – displayname