共有三个实体,即员工,人员和地址。人员与员工之间存在亲子关系(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子句中未正确应用。
有人可以帮我解决一下表达问题吗?
等待积极的答复。
答案 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
。它有助于。但这也许不是您所需要的。