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类是一个抽象类,包含字段id
和name
,并且在我的设计中被许多表使用,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]值的主要内容,如果未能解决你的问题,请参考以下文章