Eclipselink继承策略导致格式错误的查询

时间:2018-11-21 19:51:18

标签: eclipselink

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

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

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

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

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

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

}

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

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

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

从人中选择t0.PID,t0.PCODE,t1.EID,t2.AID t0左外连接地址t2 ON((t2.EID = t1.EID),员工t1在哪里((t1.PID = t0。 PID)AND(t0.PCODE ='EMP'));

预期查询为: 从人员t0中选择t0.PID,t0.PCODE,t1.EID,t2.AID员工t1左外部联接地址t2 ON(((t2.EID = t1.EID))在哪里((t1.PID = t0.PID)AND (t0.PCODE ='EMP')));

表t1在join子句中未正确应用。

有人可以帮我解决一下表达问题吗?

等待积极的答复。

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。通过另一个实体(df <- structure(list(idx = 1:20, count = c(2L, 3L, 6L, 1L, 8L, 3L, 9L, 10L, 20L, 3L, 4L, 7L, 1L, 9L, 6L, 2L, 0L, 3L, 4L, 6L)), class = "data.frame", row.names = c(NA, -20L)) )在两个未链接的实体(在您的情况下为person left join address)之间进行左联接。

我使用了JPQL。这些实体可以通过ID直接链接,但是eclipselink(2.6.2)在employee之后添加了隐式连接。并在隐式联接中引用left join中的ID。它打破了查询。我遇到了left join异常。

我通过删除"ORA-00904: "T3"."ID": invalid identifier"并添加left join和子查询解决了我的问题。我不需要从左联接中接收实体。

您可以尝试在exists上的employee之前在left join上添加显式联接。它没有帮助我。我的eclipselink在隐式联接上更改了address。但是也许你很幸运。

或者您可以在join上的left join之前在employee上添加left join。它有助于。但这也许不是您所需要的。