【问题标题】:JPA The state field path cannot be resolved to a valid typeJPA 无法将状态字段路径解析为有效类型
【发布时间】:2015-04-15 16:17:23
【问题描述】:

我需要帮助解决与 EclipseLink 2.5.x 提供程序的关系/查询。

从 ThreePhaseMotorInput 到 ValidationMessage 的关系应该是单向 OneToMany,即每个电机可以有 0..n 条消息,并且在 Java 对象图中 ValidationMessage 没有对 ThreePhaseMotorInput 的引用。

当通过 ThreePhaseMotor 访问时,JPA 无法找到属于 ValidationMessage 类的属性。 (请参阅下面的错误文本)

感谢您考虑我的问题!

查询

select msg.validationMsg, COUNT(m.id) from ThreePhaseMotorInput AS m JOIN m.valMessages AS msg GROUP BY msg.validationMsg

错误

 org.eclipse.persistence.exceptions.JPQLException: 
Exception Description: Problem compiling [select msg.validationMsg, COUNT(m.id) from ThreePhaseMotorInput AS m JOIN m.valMessages AS msg GROUP BY msg.validationMsg]. 
[7, 24] The state field path 'msg.validationMsg' cannot be resolved to a valid type.
[71, 84] The collection-valued path 'm.valMessages' cannot be resolved to a valid association field.
[119, 136] The state field path 'msg.validationMsg' cannot be resolved to a valid type.

三相电机输入

@Entity
@Table(name = "three_phase_motor_input")
public class ThreePhaseMotorInput implements IThreePhaseMotorInput, Serializable {
    private static final long serialVersionUID = 8084370807289186987L;
    @Transient
    private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Version
    private Integer version;
    private Integer status;
    @Transient
    private Integer numMessages;

    @OneToOne(cascade = CascadeType.ALL, optional = true, targetEntity = UnapprovedThreePhaseMotor.class)
    @JoinColumn(name = "unapproved_id")
    private IThreePhaseMotor unapprovedMotor;

    @OneToOne(cascade = CascadeType.ALL, optional = true, targetEntity = ApprovedThreePhaseMotor.class)
    @JoinColumn(name = "approved_id")
    private IThreePhaseMotor approvedMotor;

    @OneToMany(orphanRemoval = true, cascade = CascadeType  .ALL, fetch = FetchType.LAZY, targetEntity = ValidationMessage.class)
    @JoinColumn(name = "input_id", referencedColumnName = "id", nullable = false)
    @OrderColumn(name = "idx")
    private List<IValidationMessage> valMessages;

ValidationMessage

@Entity
@Table(name = "validation_message")
public class ValidationMessage implements Serializable, IValidationMessage {
    private static final long serialVersionUID = 8765213112015434057L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "record_id")
    private Long recordId;
    @Column(name = "field_name")
    private String fieldName;
    @Column(name = "validation_msg")
    private String validationMsg;
    private Integer status;
    @Column(name = "fail_field")
    private String failField;
    @Column(name = "error_source")
    private Integer errorSource;

【问题讨论】:

  • 您在查询中遇到问题,可能是命名查询。你能告诉我们有问题的查询吗(是这个:[select m.approvedMotor, m.valMessages, m.valMessages.validationMsg...)吗?这是命名查询还是本机查询?
  • 我在消息中拆分了查询。这是一个命名查询。
  • 我根据您在下面的回答和错误消息,用修改后的查询更新了问题。似乎无法通过 m.valMessages 到达 ValidationMessage 类。
  • 好的。得到纠正并将您的答案标记为已接受。谢谢!!
  • 我将 Andrei 的回答标记为已接受,两者都赞成,并将在 SO 允许我这样做的 22 小时内奖励赏金。

标签: jpa eclipselink


【解决方案1】:

问题似乎出在以下查询中:select m.approvedMotor, m.valMessages, m.valMessages.validationMsg, count(m.valMessages.id) from ThreePhaseMotorInput m group by m.valMessages.validationMsg

该查询应该是 JPQL 查询,即您指定实体及其 Java 属性的查询。如果你想跳转到另一个实体的属性,你也必须使用JOINs:m.valMessages.validationMsg 不正确,但INNER JOIN m.valMessages msg GROUP BY msg 是正确的。

所以试试下面的查询:

select m, COUNT(msg) from ThreePhaseMotorInput AS m LEFT JOIN m.valMessages AS msg GROUP BY msg.validationMsg

【讨论】:

    【解决方案2】:

    您不能将路径表达式与集合值关联一起使用。

    文档说:JPQL Path Expressions

    从计算结果为集合的路径表达式组成路径表达式在语法上是非法的。

    在您的查询中,m.valMessages 是非法的,因为它引用了 ValidationMessages 的集合。

    另一方面,m.approvedMotor 是合法的,因为它是单值关联。

    正如 Andrei 响应中所建议的,您需要修改您的查询以添加另一个路径表达式:

    select msg.validationMsg, COUNT(m.id) from ThreePhaseMotorInput m JOIN m.valMessages msg GROUP BY msg.validationMsg
    

    【讨论】:

      【解决方案3】:

      如果你想跳转到另一个实体的属性,你应该使用 JOIN。试试下面的 JPQL 查询

      select m, COUNT(msg) from ThreePhaseMotorInput AS m LEFT JOIN m.valMessages AS msg GROUP BY msg.validationMsg
      

      【讨论】:

        猜你喜欢
        • 2017-08-25
        • 2013-12-02
        • 2016-02-26
        • 2015-04-21
        • 2014-03-07
        • 1970-01-01
        • 1970-01-01
        • 2023-01-02
        • 2015-09-16
        相关资源
        最近更新 更多