使用 OneToMany 进行查询 - openJPA 与 EclipseLink
query with OneToMany - openJPA vs EclipseLink
openjpa 抱怨 EclipseLink 正确处理的 JPA 查询参数不正确。 EclipseLink returns 电机的验证消息集。
两个问题:
1) 我的查询是否有误,EclipseLink 是否正在处理?
2) 关于如何重构 openjpa 查询的任何建议?
感谢您考虑我的问题!
查询
SELECT m.valMessages FROM ThreePhaseMotorInput m WHERE m.id = :id
实际的 openjpa 异常
Caused by: <openjpa-2.3.0-r422266:1540826 nonfatal user error> org.apache.openjpa.persistence.ArgumentException:
Query projections cannot include array, collection, or map fields.
Invalid query: "SELECT m.valMessages FROM ThreePhaseMotorInput m WHERE m.id = :id"
at org.apache.openjpa.kernel.ExpressionStoreQuery$AbstractExpressionExecutor.assertNotContainer(ExpressionStoreQuery.java:328)
at org.apache.openjpa.kernel.ExpressionStoreQuery$DataStoreExecutor.<init>(ExpressionStoreQuery.java:770)
at org.apache.openjpa.kernel.ExpressionStoreQuery.newDataStoreExecutor(ExpressionStoreQuery.java:179)
at org.apache.openjpa.kernel.QueryImpl.createExecutor(QueryImpl.java:749)
at org.apache.openjpa.kernel.QueryImpl.compileForDataStore(QueryImpl.java:707)
at org.apache.openjpa.kernel.QueryImpl.compileForExecutor(QueryImpl.java:689)
at org.apache.openjpa.kernel.QueryImpl.compile(QueryImpl.java:589)
at org.apache.openjpa.persistence.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1038)
at org.apache.openjpa.persistence.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1017)
三相电机输入映射
public class ThreePhaseMotorInput implements IThreePhaseMotorInput, Serializable {
private static final long serialVersionUID = 8084370807289186987L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Version
private Integer version;
private Integer status;
@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 映射
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;
检查 http://docs.oracle.com/javaee/6/tutorial/doc/bnbuf.html#bnbvx - SELECT 子句:SELECT 子句不能指定集合值表达式。例如,SELECT 子句 p.teams 无效,因为 teams 是一个集合。
但是您可以将 valMessages 用于 INNER/OUTER join 和 select IValidationMessage 实体,例如:
SELECT ivm
FROM ThreePhaseMotorInput tpmi
INNER JOIN tpmi.valMessages ivm
WHERE tpmi.id = :id
openjpa 抱怨 EclipseLink 正确处理的 JPA 查询参数不正确。 EclipseLink returns 电机的验证消息集。
两个问题:
1) 我的查询是否有误,EclipseLink 是否正在处理?
2) 关于如何重构 openjpa 查询的任何建议?
感谢您考虑我的问题!
查询
SELECT m.valMessages FROM ThreePhaseMotorInput m WHERE m.id = :id
实际的 openjpa 异常
Caused by: <openjpa-2.3.0-r422266:1540826 nonfatal user error> org.apache.openjpa.persistence.ArgumentException:
Query projections cannot include array, collection, or map fields.
Invalid query: "SELECT m.valMessages FROM ThreePhaseMotorInput m WHERE m.id = :id"
at org.apache.openjpa.kernel.ExpressionStoreQuery$AbstractExpressionExecutor.assertNotContainer(ExpressionStoreQuery.java:328)
at org.apache.openjpa.kernel.ExpressionStoreQuery$DataStoreExecutor.<init>(ExpressionStoreQuery.java:770)
at org.apache.openjpa.kernel.ExpressionStoreQuery.newDataStoreExecutor(ExpressionStoreQuery.java:179)
at org.apache.openjpa.kernel.QueryImpl.createExecutor(QueryImpl.java:749)
at org.apache.openjpa.kernel.QueryImpl.compileForDataStore(QueryImpl.java:707)
at org.apache.openjpa.kernel.QueryImpl.compileForExecutor(QueryImpl.java:689)
at org.apache.openjpa.kernel.QueryImpl.compile(QueryImpl.java:589)
at org.apache.openjpa.persistence.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1038)
at org.apache.openjpa.persistence.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1017)
三相电机输入映射
public class ThreePhaseMotorInput implements IThreePhaseMotorInput, Serializable {
private static final long serialVersionUID = 8084370807289186987L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Version
private Integer version;
private Integer status;
@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 映射
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;
检查 http://docs.oracle.com/javaee/6/tutorial/doc/bnbuf.html#bnbvx - SELECT 子句:SELECT 子句不能指定集合值表达式。例如,SELECT 子句 p.teams 无效,因为 teams 是一个集合。 但是您可以将 valMessages 用于 INNER/OUTER join 和 select IValidationMessage 实体,例如:
SELECT ivm
FROM ThreePhaseMotorInput tpmi
INNER JOIN tpmi.valMessages ivm
WHERE tpmi.id = :id