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

时间:2018-09-13 23:56:05

标签: spring hibernate jpa many-to-many embeddable

大家好,我是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

此过程涉及一些课程:护士代理商命名抽象),< strong> NurseAgency 和 NurseAgencyIdentity 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;
    }
}

问题出在哪里?

1 个答案:

答案 0 :(得分:0)

尝试从以下位置更改NurseAgency上的NurseAgencyIdentity声明:

@EmbeddedId
private NurseAgencyIdentity id;

收件人:

@EmbeddedId
private NurseAgencyIdentity id = new NurseAgencyIdentity();

我没有看到完整的堆栈跟踪记录,但是当休眠状态通过对NurseAgencyIdentity的反射尝试设置字段(在您的情况下为生成的agencyId [1])时,根本原因可能是NullPointerException。

请参见org.hibernate.tuple.entity.AbstractEntityTuplizer#getIdentifier