具有一对多休眠的复合键

时间:2017-11-20 16:49:47

标签: java xml hibernate

我在尝试使这个小程序工作时遇到了一个大问题 这是我的对象:

班级国家

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

public class Country implements Serializable {

    private static final long serialVersionUID = 4947071545454L;

   private String countryID;
   private String  countryName;
   private Set<City> cities = new HashSet<City>();

    public Country() {
    }

    public Country(String countryID, String countryName, Set<City> cities) {
        this.countryID = countryID;
        this.countryName = countryName;
        this.cities = cities;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public String getCountryID() {
        return countryID;
    }

    public void setCountryID(String countryID) {
        this.countryID = countryID;
    }

    public String getCountryName() {
        return countryName;
    }

    public void setCountryName(String countryName) {
        this.countryName = countryName;
    }

    public Set<City> getCities() {
        return cities;
    }

    public void setCities(Set<City> cities) {
        this.cities = cities;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Country country = (Country) o;

        return countryID != null ? countryID.equals(country.countryID) : country.countryID == null;
    }

    @Override
    public int hashCode() {
        return countryID != null ? countryID.hashCode() : 0;
    }



    public boolean addCity(City c){
        return cities.add(c);
    }

    public boolean removeCity(City c){
        return cities.remove(c);
    }

}

班级城市

import java.io.Serializable;

public class City implements Serializable{
    private static final long serialVersionUID = 49470713545454L;

    private String cityName;
    private Country id;

    public City(String cityName, Country id) {
        this.cityName = cityName;
        this.id = id;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public Country getId() {
        return id;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        City city = (City) o;

        if (cityName != null ? !cityName.equals(city.cityName) : city.cityName != null) return false;
        return id != null ? id.equals(city.id) : city.id == null;
    }

    @Override
    public int hashCode() {
        int result = cityName != null ? cityName.hashCode() : 0;
        result = 31 * result + (id != null ? id.hashCode() : 0);
        return result;
    }
}

这是我的xml档案:

country.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.samuel.hibernate.Country" table="country" catalog="training2">

        <id name="country" type="string" column="countryID">
            <generator class="assign"/>
        </id>
        <property name="countryName" type="string">
            <column name="countryName" length="40" not-null="true" unique="true" />
        </property>

        <set name="city" inverse="true" cascade="all">
            <key column="countryID" not-null="true" />
            <one-to-many class="com.samuel.hibernate.City"/>
        </set>

    </class>
</hibernate-mapping>

city.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.samuel.hibernate.City" table="city" catalog="training2">
        <composite-id name="id">
            <key-many-to-one name="countryID" class="com.samuel.hibernate.Country"
                             column="countryID" />
            <key-property name="cityName" column="cityName" type="string"/>
        </composite-id>


    </class>
</hibernate-mapping>

这是我的主要课程:

主要课程

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import java.util.HashSet;
import java.util.Set;

public class Main {

    public static void main(String[] args) {
        System.out.println("..");

        Configuration cfg=new Configuration();
        cfg.configure("hibernate.cfg.xml");

        // aquí es donde peta si falla conexión con Postgres
        //creating seession factory object
        System.out.println("Antes de crear sesion");
        SessionFactory factory=cfg.buildSessionFactory();
        System.out.println("Despues de crear sesion");

        //creating session object
        Session session=factory.openSession();

        //creating transaction object
        Transaction t=session.beginTransaction();
        Set<City> citiesSpain = new HashSet<>();

        Country spain = new Country("es","Spain",citiesSpain);
        citiesSpain.add(new City("Barcelona",spain));
        citiesSpain.add(new City("Madrid",spain));

        session.persist(spain);

        t.commit();

        session.close();

        factory.close();


        System.out.println("END");
    }
}

当我执行此代码时,我收到以下错误消息:

Exception in thread "main" org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.component.PojoComponentTuplizer]
    at org.hibernate.tuple.component.ComponentTuplizerFactory.constructTuplizer(ComponentTuplizerFactory.java:98)
    at org.hibernate.tuple.component.ComponentTuplizerFactory.constructDefaultTuplizer(ComponentTuplizerFactory.java:119)
    at org.hibernate.tuple.component.ComponentMetamodel.<init>(ComponentMetamodel.java:68)
    at org.hibernate.mapping.Component.getType(Component.java:169)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:422)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:266)
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:451)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:710)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:726)
    at com.samuel.hibernate.Main.main(Main.java:22)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.hibernate.tuple.component.ComponentTuplizerFactory.constructTuplizer(ComponentTuplizerFactory.java:95)
    ... 10 more
Caused by: org.hibernate.PropertyNotFoundException: Could not locate getter method for property [com.samuel.hibernate.Country#cityName]
    at org.hibernate.internal.util.ReflectHelper.findGetterMethod(ReflectHelper.java:418)
    at org.hibernate.property.access.internal.PropertyAccessBasicImpl.<init>(PropertyAccessBasicImpl.java:41)
    at org.hibernate.property.access.internal.PropertyAccessStrategyBasicImpl.buildPropertyAccess(PropertyAccessStrategyBasicImpl.java:27)
    at org.hibernate.mapping.Property.getGetter(Property.java:308)
    at org.hibernate.tuple.component.PojoComponentTuplizer.buildGetter(PojoComponentTuplizer.java:138)
    at org.hibernate.tuple.component.AbstractComponentTuplizer.<init>(AbstractComponentTuplizer.java:47)
    at org.hibernate.tuple.component.PojoComponentTuplizer.<init>(PojoComponentTuplizer.java:41)
    ... 15 more

我试过在网上看,但我似乎没有找到解决方案。在我的例子中,一个国家可以拥有许多城市,但一个城市只能拥有国家。

1 个答案:

答案 0 :(得分:1)

此错误表示缺少一个或多个setter / getters 。确保为所有属性定义匹配的getter / setter。并确保您的属性正确注释。

我认为问题在于您的城市集名称在类和hbm.xml文件中是不同的。在您的实体类中,您将集合定义为Set<City> cities,并在XML文件中将此属性定义为name="city"。所以hibernate正在搜索city命名属性的setter和getter。

确保变量和属性名称一致。并在City.class中添加空构造函数。