could not set a field value by reflection setter

18,903

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.

Share:
18,903
CodeMed
Author by

CodeMed

Updated on June 19, 2022

Comments

  • CodeMed
    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 the id property of the BaseEntity superclass of the Patient 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 both Patient and Name:

    @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
    JB Nizet over 9 years
    No. I managed to make this translation by myself. Have you read my answer?
  • ivan.sim
    ivan.sim over 9 years
    @JB You beat me to it ;)
  • JB Nizet
    JB Nizet over 9 years
    Your 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
    JB Nizet over 9 years
    Patient 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
    JB Nizet over 9 years
    Then your entities may not have identical IDs. An ID is supposed to uniquely identify an entity.
  • JB Nizet
    JB Nizet over 9 years
    They 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
    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/…