org.hibernate.PropertyAccessException:无法通过反射设置字段值[1]值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了org.hibernate.PropertyAccessException:无法通过反射设置字段值[1]值相关的知识,希望对你有一定的参考价值。

嗨,大家好,我是Spring的新手,我在项目中收到此错误:

org.hibernate.PropertyAccessException: Could not set field value [1] value by 
reflection : [class  com.**.domain.identities.NurseAgencyIdentity.agencyId]
setter of com.**.domain.identities.NurseAgencyIdentity.agencyId

这个过程涉及一些类:护士,代理,命名(摘要),护士代理和护士代理。 Nurse--Agency与额外的列nurse record之间存在多对多的关系。 Named类是一个抽象类,包含字段idname,并且在我的设计中被许多表使用,id是后代表的标识符。为了实现many-to-many,我必须在最后一个类NurseAgencyIdentity中使用@Embeddable注释,这是我的NurseAgency连接表的id。这是代码:

NurseAgencyIdentity

@Embeddable
@Data
    public class NurseAgencyIdentity implements Serializable {

    @Column(name="nurse_id")
    private Long nurseId;

    @Column(name="agency_id")
    private Long agencyId;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        NurseAgencyIdentity that = (NurseAgencyIdentity) o;
        return Objects.equals(nurseId, that.nurseId) &&
                Objects.equals(agencyId, that.agencyId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(nurseId, agencyId);
    }
}

NurseAgency

@Entity
@Data
public class NurseAgency {

    @EmbeddedId
    private NurseAgencyIdentity id;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("nurseId")
    private Nurse nurse;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("agencyId")
    private Agency agency;

    private String nurseRecord;

}

护士

@Entity
@Data
public class Nurse {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String firstName;
    private String lastName;

    @Enumerated(EnumType.STRING)
    private License license;

    @OneToMany(mappedBy = "nurse", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<NurseAgency> agencies = new ArrayList<>();

    // need the extra column
    public void addAgency(Agency agency) {//, String nurseRecord) {
        NurseAgency nurseAgency = new NurseAgency();
        nurseAgency.setAgency(agency);
        nurseAgency.setNurse(this);
        //nurseAgency.setNurseRecord(nurseRecord);
        agency.getNurses().add(nurseAgency);
    }

    public void removeAgency(Agency agency) {
        for (Iterator<NurseAgency> iterator = agencies.iterator(); iterator.hasNext(); ) {
            NurseAgency nurseAgency = iterator.next();
            if (nurseAgency.getNurse().equals(this) && nurseAgency.getAgency().equals(agency)){
                iterator.remove();
                nurseAgency.getAgency().getNurses().remove(nurseAgency);
                nurseAgency.setNurse(null);
                nurseAgency.setAgency(null);
            }
        }
    }

    @Override
    public String toString() {
        return id + " " + firstName + " " + middleName + " " + lastName;
    }
}

命名

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Data
public abstract class Named implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

机构

@Entity
@Data
public class Agency extends Named {

    private String description;

    @OneToMany(mappedBy = "agency", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<NurseAgency> nurses = new ArrayList<>();

}

我尝试播种连接表时遇到此错误:

BootStrapData

@Component
public class BootStrapData implements CommandLineRunner {

    @Autowired
    private final NurseRepository nurseRepository;
    @Autowired
    private final AgencyRepository agencyRepository;
    private final NurseAgencyRepository nurseAgencyRepository;

    public BootStrapData(NurseRepository nurseRepository, AgencyRepository agencyRepository, NurseAgencyRepository nurseAgencyRepository) {
        this.nurseRepository = nurseRepository;
        this.agencyRepository = agencyRepository;
        this.nurseAgencyRepository = nurseAgencyRepository;
    }


    @Override
    public void run(String... args) throws Exception {

        System.out.println("Loading agencies ");
        ArrayList<Agency> agencies = GetAgencies();

        System.out.println("Loading Nurses ");
        ArrayList<Nurse> nurses = GetNurses(agencies);

        nurses.stream().forEach( n -> nurseRepository.save(n));
        agencies.stream().forEach( a -> agencyRepository.save(a));

        //Nurses Agencies
        ArrayList<NurseAgency> nurseAgencies = new ArrayList<>(1);
        nurseAgencies.addAll(SetNurseAndAgencies(nurses.get(0), new Agency[]{agencies.get(0), agencies.get(1), agencies.get(2)}));
        nurseAgencies.addAll(SetNurseAndAgencies(nurses.get(1), new Agency[]{agencies.get(0), agencies.get(1)}));
        nurseAgencies.addAll(SetNurseAndAgencies(nurses.get(2), new Agency[]{agencies.get(1), agencies.get(2)}));
        for (int i=0; i<nurseAgencies.size();i++){
            nurseAgencyRepository.save(nurseAgencies.get(i)); // I've got the error in first iteration in this line
    }
}


    private ArrayList<Agency> GetAgencies() {

        ArrayList<Agency> agencies = new ArrayList<>(3);

        Agency a1 = new Agency();
        a1.setName("Agency 1");
        agencies.add(a1);

        Agency a2 = new Agency();
        a2.setName("Agency 2");
        agencies.add(a2);

        Agency a3 = new Agency();
        a3.setName("Agency 3");
        agencies.add(a3);

        return agencies;
    }

    private ArrayList<Nurse> GetNurses(ArrayList<Agency> agencies) {

        ArrayList<Nurse> nurses = new ArrayList<>(3);

        Nurse n1 = new Nurse();
        n1.setFirstName("Mario");
        n1.setLastName("Perez");
        nurses.add(n1);

        Nurse n2 = new Nurse();
        n2.setFirstName("Luis");
        n2.setLastName("Ruiz");
        nurses.add(n2);

        Nurse n3 = new Nurse();
        n3.setFirstName("Maria");
        n3.setLastName("Crez");
        nurses.add(n3);

        return nurses;
    }


    private ArrayList<NurseAgency> SetNurseAndAgencies(Nurse nurse, Agency[] agencies) {

        ArrayList<NurseAgency> nurseagencies = new ArrayList<>(agencies.length);

        for (int i=0; i<agencies.length; i++){
            NurseAgency na = new NurseAgency();
            na.setNurse(nurse);
            na.setAgency(agencies[i]);
            na.setNurseRecord(nurse.getFirstName() + agencies[i].getName());
            nurseagencies.add(na);
        }
        return nurseagencies;
    }
}

问题出在哪儿?

答案

尝试更改NurseAgency上的NurseAgencyIdentity声明:

@EmbeddedId
private NurseAgencyIdentity id;

至:

@EmbeddedId
private NurseAgencyIdentity id = new NurseAgencyIdentity();

我没有看到完整的堆栈跟踪,但是当hibernate尝试通过对NurseAgencyIdentity的反射来设置字段(在你的情况下生成的agencyId [1])并且它为null时,根本原因可能是NullPointerException。

org.hibernate.tuple.entity.AbstractEntityTuplizer#getIdentifier

以上是关于org.hibernate.PropertyAccessException:无法通过反射设置字段值[1]值的主要内容,如果未能解决你的问题,请参考以下文章