Java Hibernate/Spring:NotNull属性引用null或瞬态值

Java Hibernate/Spring:NotNull属性引用null或瞬态值,java,database,spring,hibernate,dao,Java,Database,Spring,Hibernate,Dao,我正在用Java中的Hibernate、Spring和GWT开发一个应用程序。我使用Hibernate下的反向工程(使用JBossDeveloperStudio)从现有的MySQL数据库获取POJO和配置文件。这是一个非常简单的数据库,只有两个实体:国家和公民。他们之间有一对恋人的关系 代码如下: 应用程序入口点: ... Country country = new Country(); country.setNa

我正在用Java中的Hibernate、Spring和GWT开发一个应用程序。我使用Hibernate下的反向工程(使用JBossDeveloperStudio)从现有的MySQL数据库获取POJO和配置文件。这是一个非常简单的数据库,只有两个实体:国家和公民。他们之间有一对恋人的关系

代码如下:

应用程序入口点:

...

                    Country country = new Country();
                    country.setName("NameOfCountry"+i);
                    country.setPopulation(10000);

                    Citizen ctz = new Citizen();
                    ctz.setName("John");
                    ctz.setSurname("Smith");


                    ctz.setCountry(country);
                    country.getCitizens().add(ctz);

                    service.saveCitizen(ctz, new AsyncCallback<Boolean>(){

                        @Override
                        public void onFailure(Throwable caught) {
                            System.out.println("Problem saving citizen");

                        }

                        @Override
                        public void onSuccess(Boolean result) {
                            System.out.println("Citizen successfully saved");

                        }

                    });

                    service.saveCountry(country, new AsyncCallback<Boolean>(){

                        @Override
                        public void onFailure(Throwable caught) {
                            System.out.println("Problem saving country");

                        }

                        @Override
                        public void onSuccess(Boolean result) {
                            System.out.println("Country successfully saved");

                        }
                    });

...
现在,斯普林达斯:

公民道:

@Repository
public class CitizenDAO {

...
    public void saveOrUpdate(Citizen citizen){
        sessionFactory.getCurrentSession().saveOrUpdate(citizen);
    }
...
CountryDAO:

@Repository
public class CountryDAO {

...
    public void saveOrUpdate(Country country){
        sessionFactory.getCurrentSession().saveOrUpdate(country);
    }
...
最后

Citizen.hbm.xml:

<hibernate-mapping>
    <class name="sk.jakub.mod.shared.model.Citizen" table="citizen" catalog="modeldb">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <many-to-one name="country" class="sk.jakub.mod.shared.model.Country" fetch="select">
            <column name="Country_id" not-null="true" />
        </many-to-one>
        <property name="name" type="string">
            <column name="name" length="45" not-null="true" />
        </property>
        <property name="surname" type="string">
            <column name="surname" length="45" not-null="true" />
        </property>
    </class>
</hibernate-mapping>
我想不出问题出在哪里。我还尝试使用persist方法代替saveOrUpdate方法。或者也可以更改保存到数据库中的顺序。似乎什么都没用

非常感谢您的帮助:)如果需要,我可以从我的应用程序中发布更多代码

编辑: Citizen.java的代码:

public class Citizen implements java.io.Serializable {

    private static final long serialVersionUID = -3102863479088406293L;
    private Integer id;
    private Country country;
    private String name;
    private String surname;

    public Citizen() {
    }

    public Citizen(Country country, String name, String surname) {
        this.country = country;
        this.name = name;
        this.surname = surname;
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Stat getCountry() {
        return this.country;
    }

    public void setCountry(Country country) {
        this.country = country;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return this.surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }
}
Country.java:

public class Country implements java.io.Serializable {

    private static final long serialVersionUID = -4085805854508658303L;
    private Integer id;
    private String name;
    private int population;
    private Set<Citizen> citizens = new HashSet<Citizen>();

    public Country() {
    }

    public Country(String name, int population) {
        this.name = name;
        this.population = population;
    }

    public Country(String name, int population, Set<Citizen> citizens) {
        this.name = name;
        this.population = population;
        this.citizens = citizens;
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPopulation() {
        return this.population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }

    public Set<Citizen> getCitizens() {
        return this.citizens;
    }

    public void setCitizens(Set<Citizen> citizens) {
        this.citizens = citizens;
    }
}
公共类国家/地区实现java.io.Serializable{
私有静态最终长serialVersionUID=-4085805854508658303L;
私有整数id;
私有字符串名称;
私人人口;
私有集公民=新HashSet();
公共国家(){
}
公共国家(字符串名称,整数人口){
this.name=名称;
这个。人口=人口;
}
公共国家(字符串名称、整数人口、集合公民){
this.name=名称;
这个。人口=人口;
公民=公民;
}
公共整数getId(){
返回此.id;
}
公共无效集合id(整数id){
this.id=id;
}
公共字符串getName(){
返回此.name;
}
公共void集合名(字符串名){
this.name=名称;
}
公共整数getPopulation(){
还这个人口,;
}
公共人口(整数人口){
这个。人口=人口;
}
公共集getCitizens(){
归还此文件。公民;
}
公共公民(集合公民){
公民=公民;
}
}

此外,我已经手动检查了数据库,国家已保存,但公民未保存。

我看到您在创建国家之前正在创建公民。另外,两个服务调用应该在同一事务中,以便整个操作是原子的。我相信国家ID似乎是一个自我生成的ID。所以,一旦你创建了国家,你就可以把它附加到一个公民身上,但是你的调用堆栈显示你正在创建一个公民,这个公民有一个没有id的国家对象。这只是我的猜测。您可以尝试将两个调用置于同一事务下,也可以尝试创建一个国家/地区并将该国家/地区实例附加到公民。

请检查您是否正确实现了equals、hashcode和compareTo(如果适用)方法。我最近遇到了这个问题,并通过适当实施这些解决了它

似乎您正在尝试保存具有空国家/地区对象的公民POJO。你能提供国家和公民的代码吗?非常感谢。问题出在交易中。第一次保存到数据库是在一个事务中进行的,另一次保存是在另一个事务中进行的。这就是问题所在。因此,如果tehre是这样的依赖项,那么它们必须进入一个事务中。:)
org.hibernate.PropertyValueException: not-null property references a null or transient value: sk.jakub.mod.shared.model.Citizen.country 
public class Citizen implements java.io.Serializable {

    private static final long serialVersionUID = -3102863479088406293L;
    private Integer id;
    private Country country;
    private String name;
    private String surname;

    public Citizen() {
    }

    public Citizen(Country country, String name, String surname) {
        this.country = country;
        this.name = name;
        this.surname = surname;
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Stat getCountry() {
        return this.country;
    }

    public void setCountry(Country country) {
        this.country = country;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return this.surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }
}
public class Country implements java.io.Serializable {

    private static final long serialVersionUID = -4085805854508658303L;
    private Integer id;
    private String name;
    private int population;
    private Set<Citizen> citizens = new HashSet<Citizen>();

    public Country() {
    }

    public Country(String name, int population) {
        this.name = name;
        this.population = population;
    }

    public Country(String name, int population, Set<Citizen> citizens) {
        this.name = name;
        this.population = population;
        this.citizens = citizens;
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPopulation() {
        return this.population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }

    public Set<Citizen> getCitizens() {
        return this.citizens;
    }

    public void setCitizens(Set<Citizen> citizens) {
        this.citizens = citizens;
    }
}