【问题标题】:could not set a field value by reflection setter无法通过反射设置器设置字段值
【发布时间】:2014-10-07 09:00:52
【问题描述】:

在使用 hibernate 和 MySQL 的 spring mvc 应用程序中,我收到一个错误,这似乎表明 Name 实体找不到 Patient 实体的 BaseEntity 超类的 id 属性的设置器.

如何解决此错误?

这里是错误信息:

Caused by: org.hibernate.PropertyAccessException: could not set a field value by  
reflection setter of myapp.mypackage.Name.patient

这是触发错误的代码行:

ArrayList<Name> names = (ArrayList<Name>) this.clinicService.findNamesByPatientID(patntId);

这里是BaseEntity,它是Patient和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);}

}

这里是Patient 实体:

@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
}

这里是Name 实体:

@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

}

完整的堆栈跟踪可以查看at this link。

Hibernate 为上述查询生成的 SQL 为:

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

当我通过 MySQL 命令行客户端运行此查询时,它返回测试数据库表中的唯一记录。

【问题讨论】:

  • 完整的堆栈跟踪是什么样的?对于这个特定的错误消息,通常在堆栈跟踪的下半部分存在更精确、更精细的错误。
  • @isim 我也有类似的问题。你愿意帮助我吗?这是链接:stackoverflow.com/questions/25316761/…

标签: java mysql spring hibernate


【解决方案1】:

堆栈跟踪不是这么说的。堆栈跟踪没有说不能设置 ID。它说:

原因:java.lang.IllegalArgumentException:无法将 org.springframework.samples.knowledgemanager.model.HL7Patient 字段 org.springframework.samples.knowledgemanager.model.HL7USName.patient 设置为 org.springframework.samples.knowledgemanager.model .HL7USName

因此,您的 HL7USName 类有一个名为 patient 类型为 HL7Patient 的字段,并且无法使用 HL7USName 类型的值设置此字段。

这意味着您的数据库包含的 Name 具有指向 Name 类型的行而不是 Patient 类型的行的外键。

【讨论】:

  • 没有。我设法自己完成了这个翻译。你看过我的回答吗?
  • @JB 你打败了我 ;)
  • 你的实体说一个名字有一个病人。在“name”表中,有一个名为“patient_id”的列。因此,该列应该包含患者的 ID。但至少有一行在此列中有另一个名称的 ID。
  • Patient 和 Name 都是实体 BaseEntity 的实例。假设您拨打session.get(BaseEntity.class, 1)。 Hibernate 应该返回什么?病人还是名字?他们都有相同的ID。那是无效的。由于它们都是 BaseEntity 实例,因此名称可能与患者的 ID 不同。为什么 BaseEntity 是 @Entity,而不是 @MappedSuperclass?
  • 那么您的实体可能没有相同的 ID。 ID 应该唯一标识一个实体。
猜你喜欢
  • 2015-06-15
  • 2011-06-25
  • 2019-04-22
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 2010-09-14
  • 2019-05-15
  • 1970-01-01
相关资源
最近更新 更多