2015-04-01 105 views
2

openjpa抱怨EclipseLink正确处理的JPA查询的参数不正确。 EclipseLink将返回电机的验证消息集。使用OneToMany进行查询 - openJPA vs EclipseLink

两个问题:
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) 

ThreePhaseMotorInput映射

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; 

回答

3

检查http://docs.oracle.com/javaee/6/tutorial/doc/bnbuf.html#bnbvx - SELECT子句:SELECT子句无法指定集合值表达式。例如,SELECT子句p.teams无效,因为团队是一个集合。 但是你可以使用内部/外部连接,并选择IValidationMessage实体槽它valMessages,例如:

SELECT ivm 
    FROM ThreePhaseMotorInput tpmi 
INNER JOIN tpmi.valMessages ivm 
WHERE tpmi.id = :id 
+0

谢谢!我以为我在发布前尝试过,但不能有,因为你的代码第一次工作。 – 2015-04-01 15:32:59