簡體   English   中英

Hibernate / Spring:Not-null屬性引用null或transient值

[英]Hibernate/Spring: Not-null property references a null or transient value

我正在使用Java中的Hibernate,Spring和GWT開發一個應用程序。 我在Hibernate(使用JBoss Developer Studio)下使用逆向工程從現有的MySQL數據庫中獲取POJO和配置文件。 這是一個非常簡單的數據庫,只有兩個實體:國家和公民。 他們之間有OneToMany關系。

這是代碼:

app入口點:

...

                    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");

                        }
                    });

...

- service為服務器提供簡單的GWT-RPC調用

服務器上的服務:

@Service("componentService")
public class ComponentServiceImpl implements ComponentService{

    @Autowired
    private CountryDAO daoCnt;

    @Autowired
    private CitizenDAO daoCtz;

    @Transactional(readOnly=false)
    @Override
    public boolean saveCitizen(Citizen citizen) {
        daoCtz.saveOrUpdate(citizen);
        return true;
    }

    @Transactional(readOnly=false)
    @Override
    public boolean saveCountry(Country country) {
        daoCnt.saveOrUpdate(country);
        return true;
    }
}

現在SpringDAOs:

CitizenDAO:

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

Country.hbm.xml:

<hibernate-mapping>
    <class name="sk.jakub.mod.shared.model.Country" table="country" catalog="modeldb">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <property name="name" type="string">
            <column name="name" length="45" not-null="true" />
        </property>
        <property name="population" type="int">
            <column name="population" not-null="true" />
        </property>
        <set name="citizens" table="citizen" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="Country_id" not-null="true" />
            </key>
            <one-to-many class="sk.jakub.mod.shared.model.Citizen" />
        </set>
    </class>
</hibernate-mapping>

我沒有列出Citizen.java和Country.java,因為它們只是基本的POJO(如果需要我會提供它們)。

當我啟動我的應用程序並且我想將數據保存到數據庫時,我獲得以下錯誤:

org.hibernate.PropertyValueException: not-null property references a null or transient value: sk.jakub.mod.shared.model.Citizen.country 

我無法弄清楚問題出在哪里。 我也嘗試了而不是saveOrUpdate方法,persist方法。 或者還要更改保存到數據庫的順序。 似乎沒什么用。

非常感謝您的幫助:)如果需要,我可以從我的應用程序發布更多代碼。

編輯: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;
    }
}

此外,我手動檢查了數據庫,保存了國家,但公民卻沒有。

在創建國家之前,我看到你正在創建一個公民。 此外,兩個服務調用都應該在同一個事務中,以使整個操作成為原子操作。 COUNTRY_ID似乎是我相信的自我生成的ID。 因此,一旦您創建了國家/地區,您就可以將其附加到公民,但是您調用堆棧顯示您正在創建一個擁有Country對象且沒有id的公民。 這只是我的猜測。 您可以嘗試將兩個呼叫置於同一個交易下,也可以嘗試創建一個國家/地區並將該國家/地區實例附加到Citizen。

請檢查您是否正確實現了equals,hashcode和compareTo(如果適用)方法。 我最近遇到了這個問題,並通過適當的實施來解決這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM