Java 使用主键嵌入对象时发生休眠错误
我有一个名为Place的@MappedSuperclass,它有一个名为uniqueId和name的变量。我还有乡村班和城市班,扩展了地方班。城市类@Embeddeble有一个变量称为mayor,乡村类@Entity有一个变量称为president。Country类有两个嵌入对象,称为capital_city和Maximum_city。当我持久化Country对象时,会出现Hibernate错误,表明使用@AttributeOverride从uniqueId重命名的Country_id没有默认值。insert语句实际上没有country\u id的值。当我查看create语句时,它将最大的城市id定义为主键。。。我不明白为什么Hibernate会这样做。我需要将country_id作为主键,并简单地嵌入两个City对象。代码如下Java 使用主键嵌入对象时发生休眠错误,java,hibernate,Java,Hibernate,我有一个名为Place的@MappedSuperclass,它有一个名为uniqueId和name的变量。我还有乡村班和城市班,扩展了地方班。城市类@Embeddeble有一个变量称为mayor,乡村类@Entity有一个变量称为president。Country类有两个嵌入对象,称为capital_city和Maximum_city。当我持久化Country对象时,会出现Hibernate错误,表明使用@AttributeOverride从uniqueId重命名的Country_id没有默认值
// Place class
@MappedSuperclass
public abstract class Place {
private String uniqueId;
private String name;
@Id
public String getUniqueId() {
return uniqueId;
}
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
}
@Column(nullable=true, unique=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// Country class
@Entity
@AttributeOverride (name="uniqueId", column=@Column(name="country_id"))
public class Country extends Place {
private City capitalCity;
private City largestCity;
private String president = "";
public Country() { }
public Country(String id, String name, City capital, City largest, String prez) {
this.setUniqueId(id);
this.setName(name);
capitalCity = capital;
largestCity = largest;
president = prez;
}
public String getPresident() {
return president;
}
public void setPresident(String president) {
this.president = president;
}
@Embedded
@AttributeOverrides ({
@AttributeOverride (name="uniqueId", column=@Column(name="capital_city_id")),
@AttributeOverride (name="name", column=@Column(name="capital_city_name")),
@AttributeOverride (name="mayor", column=@Column(name="capital_city_mayor"))
})
public City getCapitalCity() {
return capitalCity;
}
public void setCapitalCity(City capitalCity) {
this.capitalCity = capitalCity;
}
@Embedded
@AttributeOverrides ({
@AttributeOverride (name="uniqueId", column=@Column(name="largest_city_id")),
@AttributeOverride (name="name", column=@Column(name="largest_city_name")),
@AttributeOverride (name="mayor", column=@Column(name="largest_city_mayor"))
})
public City getLargestCity() {
return largestCity;
}
public void setLargestCity(City largestCity) {
this.largestCity = largestCity;
}
}
// City class
@Embeddable
public class City extends Place {
private String mayor;
public City() {}
public City(String m, String id, String name) {
mayor = m;
this.setUniqueId(id);
this.setName(name);
}
public String getMayor() {
return mayor;
}
public void setMayor(String mayor) {
this.mayor = mayor;
}
}
// Main
import test.City;
import test.Country;
public class Main {
public static void main(String[] args) {
City capital = new City("Tom Smith","1010","Fairview");
City largest = new City("Jo Somebody","2010","Crestfall");
Country country = new Country("USA","United States",
capital, largest, "George Jefferson");
AnnotationConfiguration cfg = new AnnotationConfiguration();
Session session = cfg.configure("hibernate.cfg.xml").buildSessionFactory().openSession();
Transaction t=session.beginTransaction();
session.persist(country);
t.commit();
session.close();
}
}
// Bibernate Create SQL codes
Hibernate: drop table if exists Country
Hibernate: create table Country (country_id varchar(255) not null, name varchar(255),
capital_city_id varchar(255) not null, capital_city_mayor varchar(255),
capital_city_name varchar(255), largest_city_id varchar(255) not null,
largest_city_mayor varchar(255), largest_city_name varchar(255),
president varchar(255), primary key (largest_city_id))
Hibernate: insert into Country (name, capital_city_mayor, capital_city_name,
largest_city_mayor, largest_city_name, president, largest_city_id) values
(?, ?, ?, ?, ?, ?, ?)
请注意,主键是最大的城市id,而不是国家id
// Hibernate error message
Caused by: java.sql.SQLException: Field 'country_id' doesn't have a default value
请帮忙!!!我将Hibernate符号添加到现有的代码库中,因此我没有太多修改代码的自由。希望通过正确的Hibernate注释可以实现这一点。我相信@MappedSuperclass只能通过@Entitys而不是@Embeddebles进行扩展。说
指定一个类,该类的映射信息应用于从该类继承的实体
不管怎么说,我认为问题在于,当你@Embed the City in Country时,你也在嵌入第二个@Id属性。您有一个由Country从Place继承的@Id属性,还有一个来自嵌入城市的@Id属性。一个国家基本上有两个唯一标识。与其让Place成为@MappeAttribute,不如让它成为没有任何JPA注释的接口:
public interface Place {
String getUniqueId();
void setUniqueId(String uniqueId);
String getName();
setName(String name);
}
您可以获得多态性的好处,而不必费心弄清楚正确的JPA映射或[ab]使用@AttributeOverride