org.hibernate.PropertyAccessException: не удалось установить значение поля [1] по отражению - PullRequest
0 голосов
/ 14 сентября 2018

Привет, ребята. Я новичок в 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

В этом процессе участвуют несколько классов: Медсестра , Агентство, Именованные ( аннотация ), NurseAgency и NurseAgencyIdentity .Между Nurse--Agency и дополнительным столбцом nurse record существует отношение «многие ко многим».Класс Named является абстрактным классом, который содержит поля id и name и используется многими таблицами в моем проекте, являясь id идентификатором таблицы-потомка.Для реализации many-to-many мне пришлось использовать аннотацию @Embeddable в последнем классе NurseAgencyIdentity , которая является идентификатором моей таблицы соединения NurseAgency .Вот код:

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 голосов
/ 03 ноября 2018

Попробуйте изменить объявление NurseAgencyIdentity в NurseAgency с:

@EmbeddedId
private NurseAgencyIdentity id;

до:

@EmbeddedId
private NurseAgencyIdentity id = new NurseAgencyIdentity();

Я не видел полную трассировку стека, но основной причиной может быть исключение NullPointerException, когда hibernate пытается задать поля (в вашем случае сгенерированный agencyId [1]) через отражение в NurseAgencyIdentity, и оно равно null.

См. org.hibernate.tuple.entity.AbstractEntityTuplizer # getIdentifier

...