2012-09-18 75 views
0

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

下面是代碼:

應用程序入口點:

- 服務提供了簡單的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方法,堅持方法。或者也可以改變保存到數據庫的順序。似乎沒有任何工作。

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

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

此外,我手動檢查數據庫和國家被保存,但公民不是。

+1

好像您正在嘗試保存具有空國家對象的Citizen POJO。你能否包括國家和公民的代碼? –

+0

源碼參考資料:) – Reshi

回答

2

我看到您在創建國家之前創建了一個Citizen。同時這兩個服務調用應該在整個操作的同一事務中是原子的。 COUNTRY_ID似乎是我相信的自我生成的ID。所以一旦你創建了國家,你可以將它附加到公民身上,但是你可以調用堆棧顯示你正在創建一個擁有沒有ID的國家對象的公民。這只是我的猜測。您可以嘗試將這兩個調用放在同一個事務中,並嘗試創建一個國家並將該國家/地區實例附加到Citizen。

+0

非常感謝。問題出在交易中。首先保存到數據庫進入一個事務,另一個保存進入另一個事務。這就是問題所在。所以,如果這樣的依賴關係,他們必須進行一次交易。 :) – Reshi

+0

是的,它應該在交易的一兜帽! :-) – raddykrish

0

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

相關問題