could not set a field value by reflection setter
That's not what the stack trace says. The stack trace doesn't say that the ID can't be set. It says:
Caused by: java.lang.IllegalArgumentException: Can not set org.springframework.samples.knowledgemanager.model.HL7Patient field org.springframework.samples.knowledgemanager.model.HL7USName.patient to org.springframework.samples.knowledgemanager.model.HL7USName
So, your HL7USName class has a field named patient
of type HL7Patient
, and it's impossible to set this field with a value of type HL7USName.
This means that your database contains a Name that has a foreign key to a row of type Name instead of a row of type Patient.
CodeMed
Updated on June 19, 2022Comments
-
CodeMed almost 2 years
In a spring mvc application using hibernate and MySQL, I am getting an error which seems to indicate that a
Name
entity cannot find the setter for theid
property of theBaseEntity
superclass of thePatient
entity.How can I resolve this error?
Here is the error message:
Caused by: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of myapp.mypackage.Name.patient
Here is the line of code that triggers the error:
ArrayList<Name> names = (ArrayList<Name>) this.clinicService.findNamesByPatientID(patntId);
Here is the
BaseEntity
, which is the superclass of bothPatient
andName
:@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @DiscriminatorFormula("(CASE WHEN dtype IS NULL THEN 'BaseEntity' ELSE dtype END)") public class BaseEntity { @Transient private String dtype = this.getClass().getSimpleName(); @Id @GeneratedValue(strategy = GenerationType.TABLE) protected Integer id; public void setId(Integer id) {this.id = id;} public Integer getId() {return id;} public void setDtype(String dt){dtype=dt;} public String getDtype(){return dtype;} public boolean isNew() {return (this.id == null);} }
Here is the
Patient
entity:@Entity @Table(name = "patient") public class Patient extends BaseEntity{ @OneToMany(mappedBy = "patient") private Set<Name> names; protected void setNamesInternal(Set<Name> nms) {this.names = nms;} protected Set<Name> getNamesInternal() { if (this.names == null) {this.names = new HashSet<Name>();} return this.names; } public List<Name> getNames() { List<Name> sortedNames = new ArrayList<Name>(getNamesInternal()); PropertyComparator.sort(sortedNames, new MutableSortDefinition("family", true, true)); return Collections.unmodifiableList(sortedNames); } public void addName(Name nm) { getNamesInternal().add(nm); nm.setPatient(this); } //other stuff }
Here is the
Name
entity:@Entity @Table(name = "name") public class Name extends BaseEntity{ @ManyToOne @JoinColumn(name = "patient_id") private Patient patient; public Patient getPatient(){return patient;} public void setPatient(Patient ptnt){patient=ptnt;} //other stuff }
The complete stack trace can be viewed at this link.
The SQL generated by Hibernate for the above query is:
select distinct hl7usname0_.id as id1_0_0_, givennames1_.id as id1_45_1_, hl7usname0_.family as family1_44_0_, hl7usname0_.patient_id as patient3_44_0_, hl7usname0_.person_id as person4_44_0_, hl7usname0_.suffix as suffix2_44_0_, hl7usname0_.usecode as usecode5_44_0_, hl7usname0_.codesystem as codesyst6_44_0_, givennames1_.given as given2_45_1_, givennames1_.name_id as name3_45_1_, givennames1_.name_id as name3_0_0__, givennames1_.id as id1_45_0__ from hl7_usname hl7usname0_ left outer join hl7_usname_given givennames1_ on hl7usname0_.id=givennames1_.name_id where hl7usname0_.patient_id=1
When I run this query through the MySQL command line client, it returns the only record in the test database table.
-
JB Nizet over 9 yearsNo. I managed to make this translation by myself. Have you read my answer?
-
ivan.sim over 9 years@JB You beat me to it ;)
-
JB Nizet over 9 yearsYour entity says that a Name has a Patient. In the table "name", you have a column named "patient_id". This column is thus supposed to contain the ID of a patient. But at least one row has the ID of another name in this column.
-
JB Nizet over 9 yearsPatient and Name are both instances of the entity BaseEntity. Suppose you call
session.get(BaseEntity.class, 1)
. What should Hibernate return? The patient or the name? They both have the same ID. That is invalid. Since they are both BaseEntity instances, a Name may not have the same ID as a Patient. Why is BaseEntity an@Entity
, and not a@MappedSuperclass
? -
JB Nizet over 9 yearsThen your entities may not have identical IDs. An ID is supposed to uniquely identify an entity.
-
JB Nizet over 9 yearsThey shouldn't have an auto-increment, since their ID is supposed to be generated from the sequence number stored in the table used by
GenerationType.TABLE
. Use this table in your scripts as well, or a counter, or whatever, but make sure IDs don't conflict. -
CodeMed over 9 years@JBNizet I added a second edit with more code to my similar posting. I am trying to understand how hibernate manages manytoone relationships. Are you willing to help me with it? Here is the link: stackoverflow.com/questions/25316761/…