0

JavaでHibernate、Spring、およびGWTを使用してアプリケーションを開発しています。Hibernate (JBoss Developer Studio を使用) でリバース エンジニアリングを使用して、既存の MySQL データベースから POJO と構成ファイルを取得しました。これは、Country と Citizen の 2 つのエンティティのみを含む非常に単純なデータベースです。それらの間にはOneToManyの関係があります。

コードは次のとおりです。

アプリのエントリ ポイント:

...

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

                        }
                    });

...

-- サービスはサーバーへの単純な 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;
    }
}

現在、SpringDAO:

シチズンDAO:

@Repository
public class CitizenDAO {

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

国DAO:

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

さらに、データベースを手動で確認したところ、国は保存されていますが、市民は保存されていません。

4

2 に答える 2

2

国を作成する前に市民を作成しているようです。また、操作全体をアトミックにするには、両方のサービス呼び出しが同じトランザクション内にある必要があります。COUNTRY_ID は、私が信じている自己生成 ID のようです。したがって、国を作成したら、それを市民にアタッチできますが、スタックを呼び出すと、id を持たない Country オブジェクトを持つ市民を作成していることがわかります。これは私の推測です。両方の呼び出しを同じトランザクションの下に置き、Country を作成してその国のインスタンスを Citizen にアタッチすることもできます。

于 2012-09-18T19:40:20.493 に答える
0

equals、hashcode、compareTo (該当する場合) メソッドが適切に実装されているかどうかを確認してください。私は最近この問題に直面し、これらを適切に実装することで解決しました。

于 2015-07-13T22:52:29.690 に答える