Java 休眠:无法通过 com.mahlzeit.datamodel.address.City.id 的反射设置器设置字段值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29971987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:55:18  来源:igfitidea点击:

Hibernate: could not set a field value by reflection setter of com.mahlzeit.datamodel.address.City.id

javahibernate

提问by displayname

I'm trying to add a Cityto a Countryusing a @ManyToOnerelationship. The problem is that I am getting a org.hibernate.PropertyAccessExceptionas I try to save my entities.

我正在尝试使用关系将 a 添加City到 a 。问题是当我试图保存我的实体时,我得到了一个。Country@ManyToOneorg.hibernate.PropertyAccessException

private void addAddressData() {
    Session session = sessionFactory.openSession();     
    session.beginTransaction();

    List<Country> countryList = new ArrayList<>();      
    Country austria = new Country("at");
    countryList.add(new Country("de"));
    countryList.add(austria);

    for(Country country : countryList) {            
        try {       
            session.save(country);
        } catch (ConstraintViolationException e) {
            e.printStackTrace();
        }           
    }

    List<City> cityList = new ArrayList<>();        
    cityList.add(new City(austria, "Graz"));
    cityList.add(new City(austria, "Wien"));

    for(City city : cityList) {         
        try {       
            session.save(city);
        } catch (ConstraintViolationException e) {
            e.printStackTrace();
        }           
    }

    session.getTransaction().commit();          
}

It seems like I need to specify the relation different or at least tell Hibernate where it can find the Countryid. It surely is just an annotation thing ..

似乎我需要指定不同的关系,或者至少告诉 Hibernate 在哪里可以找到Countryid。它肯定只是一个注释的东西..

Please Note:I auto-generated all setters and getters but removed them for the sake of code length here on SO.

请注意:我自动生成了所有的 setter 和 getter,但为了代码长度,我在 SO 上删除了它们。

Country.java

国家.java

@Entity
public class Country implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -2060021861139912774L;

    @Id 
    @GeneratedValue
    @Column(name="id")
    private Long id; // = null; (was not the problem)

    @Column(unique=true)
    private String countryCode;

    public Country(String country_code) {
        this.countryCode = country_code;
    }

    public String getCountryCode() {
        return countryCode;
    }

    public void setCountryCode(String countryCode) { 
        this.countryCode = countryCode;
    }

    public Long getId() {
        return id;
    }

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

    @Override
    public String toString() {
        return "Country [id=" + id.toString() + ", country_code=" + countryCode.toString()  +"]";
    }
}

City.java

城市.java

@Entity
public class City implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -4374113410767348574L;

    @Id
    @GeneratedValue
    @Column(name="id")
    private Long id;

    @Id
    @ManyToOne
    private Country country;

    private String cityName;

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

    public Long getId() {
        return id;
    }

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

    public String getCityName() {
        return cityName;
    }

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

    public Country getCountry() {
        return country;
    }

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


     @Override
    public String toString() {
        return "City [id=" + id.toString() + ", country_id="
                + getCountry().toString() + ", cityName=" + cityName + "]";
    }
}

Stacktrace

堆栈跟踪

Exception in thread "main" org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.mahlzeit.datamodel.address.City.id
    at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:150)
    at org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:436)
    at org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:121)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:120)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:204)
    at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:189)
    at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:642)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:635)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:631)
    at com.mahlzeit.datamodel.HibernateTest.addAddressData(HibernateTest.java:57)
    at com.mahlzeit.datamodel.HibernateTest.main(HibernateTest.java:31)
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Long field com.mahlzeit.datamodel.address.City.id to org.hibernate.id.IdentifierGeneratorHelper
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(Unknown Source)
    at java.lang.reflect.Field.set(Unknown Source)
    at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:138)
    ... 13 more

采纳答案by cн?dk

The definition of the oneToManymapping between the two classes is incorrect.

oneToMany两个类之间的映射定义不正确。

@Id //wrong annotation here
@ManyToOne
private Country country;

Should be:

应该:

@ManyToOne
@JoinColumn(name="id") //the country id, better rename it country_id
private Country country;

The @Idis misplaced here and Hibernate get confused because there are two columns annotated @Id, and in your Countryclass you should declare a set of cities to complete the mapping, like this:

@Id这里放错位置和Hibernate会感到困惑,因为有注释的两列@Id,并在你的Country类,你应该声明一组城市完成映射,如下所示:

@OneToMany(mappedBy="country")
private Set<City> cities;

//the right getters and setters for cities

For further information about One To Many mapping take a look at this Hibernate One To Many Annotation Tutorial.

有关一对多映射的更多信息,请查看此Hibernate 一对多注释教程