Eclipselink Inheritance policy causing malformed query

孤街浪徒 提交于 2019-12-11 23:45:00

问题


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).

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

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

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

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:

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'));

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')));

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

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

Waiting for a positive reply.


回答1:


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

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".

I solved my problem by removing left join and adding exists and subquery. I did not need to receive entity from left 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.

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



来源:https://stackoverflow.com/questions/53419566/eclipselink-inheritance-policy-causing-malformed-query

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!