Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用主键嵌入对象时发生休眠错误_Java_Hibernate - Fatal编程技术网

Java 使用主键嵌入对象时发生休眠错误

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的@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对象。代码如下

// 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