Eclipselink继承策略导致格式错误的查询 [英] Eclipselink Inheritance policy causing malformed query

查看:82
本文介绍了Eclipselink继承策略导致格式错误的查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

共有三个实体,即员工,人员和地址。人员与员工之间存在亲子关系(Employee IS-A Person)。
人与地址之间存在1:1的关系。 (假定一个人有一个永久地址。)

There are three entities namely Employee, Person and Address. There is a parent-child relationship between Person and Employee (Employee IS-A Person). There is a 1:1 relationship from Person to Address. (A Person is assumed to have one permanent address).

Employee类的关键属性是:1. employeeId(pk)2. personId(fk)

The key properties of Employee class are: 1. employeeId(pk) 2. personId(fk)

Person类的关键属性是:1. pId(pk)2. pCode

The key properties of Person class are: 1. pId(pk) 2. pCode

Address类的关键属性是:1. addressId(pk)2. employeeId(fk)

The key properties of Address class are: 1. addressId(pk) 2. employeeId(fk)

以下是Person,Employee和Address类的描述符代码片段:

The following are the descriptor code snippets for Person, Employee and Address classes:

public RelationalDescriptor buildPersonDescriptor() {
RelationalDescriptor descriptor = new RelationalDescriptor();
descriptor.setJavaClass(Person.class);
descriptor.addTableName("PERSON");
descriptor.addPrimaryKeyFieldName("PERSON.PID");

// Inheritance properties.
descriptor.getInheritancePolicy().setClassIndicatorFieldName("PERSON.PCODE");
descriptor.getInheritancePolicy().addClassIndicator(Employee.class, "EMP");

// RelationalDescriptor properties.
descriptor.useSoftCacheWeakIdentityMap();
descriptor.setIdentityMapSize(100);
descriptor.useRemoteSoftCacheWeakIdentityMap();
descriptor.setRemoteIdentityMapSize(100);
descriptor.setSequenceNumberFieldName("PERSON.PID");
descriptor.setSequenceNumberName("PERSON_SEQ");
descriptor.setAlias("Person");

// Query manager.
descriptor.getDescriptorQueryManager().checkCacheForDoesExist();
//Named Queries


DirectToFieldMapping productIDMapping = new DirectToFieldMapping();
productIDMapping.setAttributeName("pId");
productIDMapping.setFieldName("PERSON.PID");
descriptor.addMapping(productIDMapping);

DirectToFieldMapping productIDMapping = new DirectToFieldMapping();
productIDMapping.setAttributeName("pCode");
productIDMapping.setFieldName("PERSON.PCODE");
descriptor.addMapping(productIDMapping);


return descriptor;

}

public RelationalDescriptor buildEmployeeDescriptor() {

RelationalDescriptor descriptor = new RelationalDescriptor();
descriptor.setJavaClass(Employee.class);
descriptor.addTableName("EMPLOYEE");

// Inheritance properties.
descriptor.getInheritancePolicy().setParentClass(Person.class);

// RelationalDescriptor properties.

descriptor.setAlias("Employee");

// Query manager.
descriptor.getDescriptorQueryManager().checkCacheForDoesExist();
//Named Queries

// Event manager.

// Mappings.
DirectToFieldMapping employeeIdMapping = new DirectToFieldMapping();
employeeIdMapping.setAttributeName("employeeId");
employeeIdMapping.setFieldName("EMPLOYEE.EID");
descriptor.addMapping(employeeIdMapping);

DirectToFieldMapping personIdMapping = new DirectToFieldMapping();
personIdMapping.setAttributeName("personId");
personIdMapping.setFieldName("EMPLOYEE.PID");
descriptor.addMapping(personIdMapping);

OneToOneMapping addressMapping = new OneToOneMapping();
addressMapping.setAttributeName("address");
addressMapping.setReferenceClass(Address.class);
addressMapping.dontUseIndirection();
addressMapping.addTargetForeignKeyFieldName("ADDRESS.EID", "EMPLOYEE.EID");
descriptor.addMapping(addressMapping);

return descriptor;

}

    public RelationalDescriptor buildAddressDescriptor() {

RelationalDescriptor descriptor = new RelationalDescriptor();
  descriptor.setJavaClass(com.tropics.application.products.domain.costingandpricing.SellingPriceAddOn.class);
  descriptor.addTableName("ADDRESS");
  descriptor.addPrimaryKeyFieldName("ADDRESS.AID");

  // Descriptor properties.
  descriptor.useSoftCacheWeakIdentityMap();
  descriptor.setIdentityMapSize(100);
  descriptor.useRemoteSoftCacheWeakIdentityMap();
  descriptor.setRemoteIdentityMapSize(100);
  descriptor.setSequenceNumberFieldName("ADDRESS.AID");
  descriptor.setSequenceNumberName("ADDRESS_SEQ");
  descriptor.setAlias("address");

  // Query manager.
  descriptor.getDescriptorQueryManager().checkCacheForDoesExist();

  //Mappings

  DirectToFieldMapping personIDMapping = new DirectToFieldMapping();
  personIDMapping.setAttributeName("employeeId");
  personIDMapping.setFieldName("ADDRESS.EID");
  descriptor.addMapping(personIDMapping);

  DirectToFieldMapping addressIDMapping = new DirectToFieldMapping();
  addressIDMapping.setAttributeName("addressId");
  addressIDMapping.setFieldName("ADDRESS.AID");
  descriptor.addMapping(addressIDMapping);  

}

以下是用于生成动态查询的代码段:

Following is the code snippet for generating the dynamic query:

ExpressionBuilder employee = new ExpressionBuilder();
ReportQuery query = new ReportQuery(Employee.class,employee);
Expression address = employee.getAllowingNull("address");
query.addAttribute("pId");
query.addAttribute("pCode");
query.addAttribute("employeeId");
query.addAttribute("addressId",address.get("addressId"));
query.addNonFetchJoin(employee.leftJoin(address, 
 address.get("employeeId")));

resultCollection = (Vector) clientSessionHolder.eclipselinkClientSession().executeQuery(query);

在运行该程序时,根据日志生成的查询:

On running this program, the query which is generated as per logs:

从人中选择t0.PID,t0.PCODE,t1.EID,t2.AID t0左外连接地址t2 ON(((t2.EID = t1.EID),EMPLOYEE t1 WHERE((t1 .PID = t0.PID)AND(t0.PCODE ='EMP'));

SELECT t0.PID, t0.PCODE, t1.EID, t2.AID FROM PERSON t0 LEFT OUTER JOIN ADDRESS t2 ON ((t2.EID = t1.EID),EMPLOYEE t1 WHERE ((t1.PID = t0.PID) AND (t0.PCODE = 'EMP'));

期望的查询为:
选择t0.PID,t0。 PCODE,t1.EID,t2.AID来自人员t0,员工t1左外连接地址t2 ON((t2.EID = t1.EID)其中((t1.PID = t0.PID)AND(t0.PCODE ='EMP ')))

The expected query is: SELECT t0.PID, t0.PCODE, t1.EID, t2.AID FROM PERSON t0,EMPLOYEE t1 LEFT OUTER JOIN ADDRESS t2 ON ((t2.EID = t1.EID) WHERE ((t1.PID = t0.PID) AND (t0.PCODE = 'EMP')));

联接子句中未正确应用表t1。

The table t1 is not correctly applied in the join clause.

有人可以帮忙吗?我的表达式有什么问题?

Could anyone help me with what's wrong with the expression?

等待一个肯定的答复。

推荐答案

我遇到了同样的问题,两个未链接的实体(在您的情况下为个人左连接地址)之间的左连接通过另一个实体(员工)。

I ran into the same problem. Left join between two not linked entities (person left join address in your case) through another entities (employee).

我使用了JPQL。这些实体可以通过ID直接链接,但是eclipselink(2.6.2)在左连接之后添加了隐式连接。并从隐式联接中引用ID(在左联接中)。它打破了查询。我得到了异常 ORA-00904: T3。 ID:无效的标识符

I used JPQL. These entities could be linked directly by IDs, but eclipselink (2.6.2) added implicit join after the left join. And referred (in left join) to ID from implicit join. It broke the query. I got the exception "ORA-00904: "T3"."ID": invalid identifier".

我通过删除左联接并添加 exists 和子查询。我不需要从左联接中接收实体。

I solved my problem by removing left join and adding exists and subquery. I did not need to receive entity from left join.

您可以尝试在雇员上添加显式联接,然后在<在地址上的code>左联接。它没有帮助我。我的eclipselink在隐式联接上更改了 join 。但是,也许您很幸运。

You can try add explicit join on employee before the left join on address. It did not help me. My eclipselink changing join on implicit join. But maybe you are lucky.

或者您可以在雇员上添加左联接 地址左联接之前的code>。它有助于。但这也许不是您所需要的。

Or you can add left join on employee before the left join on address. It helps. But maybe this is not what you need.

这篇关于Eclipselink继承策略导致格式错误的查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆