Eclipselink Inheritance policy causing malformed query
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.
eclipselink
|
show 1 more comment
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.
eclipselink
Why are you using "query.addNonFetchJoin(employee.leftJoin(address, address.get("employeeId")));" at all? Try removing it and show the SQL as it is just duplicating what you already added with the employee.getAllowingNull("address") calls.
– Chris
Nov 22 '18 at 4:05
@Chris Even after commenting the query.addNonFetchJoin() line, still getting the below exception: org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "T1"."EID": invalid identifier. The malformed query still is: 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')); Don't understand why EMPLOYEE t1 not appended after PERSON t0 and before JOIN keyword in the query. Is it an issue with descriptor or expression?
– anup nair
Nov 22 '18 at 11:33
First, EID isn't the primary key in Employee/Person which confuses things slightly for EclipseLink, but it should be able to handle it. It seems you are hitting an issue with optimization logic which thinks that Employee table doesn't matter, which is incorrect for your mapping setup to a non-pk field. I haven't dealt with the native descriptor logic in quite a few years, but I'm sure there is a setting somewhere to fix this, it just will take some effort to track down on the inheritance policy class.
– Chris
Nov 22 '18 at 15:57
@Chris do you think adding descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") to employee descriptor configuration would resolve this as it's primay key of EMPLOYEE table and foreign key in Address table?
– anup nair
Nov 23 '18 at 4:41
@Chris I added descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") in buildEmployeeDescriptor() method but still getting same malformed query. Any clue?
– anup nair
Nov 23 '18 at 13:03
|
show 1 more comment
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.
eclipselink
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.
eclipselink
eclipselink
asked Nov 21 '18 at 19:51
anup nairanup nair
32
32
Why are you using "query.addNonFetchJoin(employee.leftJoin(address, address.get("employeeId")));" at all? Try removing it and show the SQL as it is just duplicating what you already added with the employee.getAllowingNull("address") calls.
– Chris
Nov 22 '18 at 4:05
@Chris Even after commenting the query.addNonFetchJoin() line, still getting the below exception: org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "T1"."EID": invalid identifier. The malformed query still is: 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')); Don't understand why EMPLOYEE t1 not appended after PERSON t0 and before JOIN keyword in the query. Is it an issue with descriptor or expression?
– anup nair
Nov 22 '18 at 11:33
First, EID isn't the primary key in Employee/Person which confuses things slightly for EclipseLink, but it should be able to handle it. It seems you are hitting an issue with optimization logic which thinks that Employee table doesn't matter, which is incorrect for your mapping setup to a non-pk field. I haven't dealt with the native descriptor logic in quite a few years, but I'm sure there is a setting somewhere to fix this, it just will take some effort to track down on the inheritance policy class.
– Chris
Nov 22 '18 at 15:57
@Chris do you think adding descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") to employee descriptor configuration would resolve this as it's primay key of EMPLOYEE table and foreign key in Address table?
– anup nair
Nov 23 '18 at 4:41
@Chris I added descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") in buildEmployeeDescriptor() method but still getting same malformed query. Any clue?
– anup nair
Nov 23 '18 at 13:03
|
show 1 more comment
Why are you using "query.addNonFetchJoin(employee.leftJoin(address, address.get("employeeId")));" at all? Try removing it and show the SQL as it is just duplicating what you already added with the employee.getAllowingNull("address") calls.
– Chris
Nov 22 '18 at 4:05
@Chris Even after commenting the query.addNonFetchJoin() line, still getting the below exception: org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "T1"."EID": invalid identifier. The malformed query still is: 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')); Don't understand why EMPLOYEE t1 not appended after PERSON t0 and before JOIN keyword in the query. Is it an issue with descriptor or expression?
– anup nair
Nov 22 '18 at 11:33
First, EID isn't the primary key in Employee/Person which confuses things slightly for EclipseLink, but it should be able to handle it. It seems you are hitting an issue with optimization logic which thinks that Employee table doesn't matter, which is incorrect for your mapping setup to a non-pk field. I haven't dealt with the native descriptor logic in quite a few years, but I'm sure there is a setting somewhere to fix this, it just will take some effort to track down on the inheritance policy class.
– Chris
Nov 22 '18 at 15:57
@Chris do you think adding descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") to employee descriptor configuration would resolve this as it's primay key of EMPLOYEE table and foreign key in Address table?
– anup nair
Nov 23 '18 at 4:41
@Chris I added descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") in buildEmployeeDescriptor() method but still getting same malformed query. Any clue?
– anup nair
Nov 23 '18 at 13:03
Why are you using "query.addNonFetchJoin(employee.leftJoin(address, address.get("employeeId")));" at all? Try removing it and show the SQL as it is just duplicating what you already added with the employee.getAllowingNull("address") calls.
– Chris
Nov 22 '18 at 4:05
Why are you using "query.addNonFetchJoin(employee.leftJoin(address, address.get("employeeId")));" at all? Try removing it and show the SQL as it is just duplicating what you already added with the employee.getAllowingNull("address") calls.
– Chris
Nov 22 '18 at 4:05
@Chris Even after commenting the query.addNonFetchJoin() line, still getting the below exception: org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "T1"."EID": invalid identifier. The malformed query still is: 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')); Don't understand why EMPLOYEE t1 not appended after PERSON t0 and before JOIN keyword in the query. Is it an issue with descriptor or expression?
– anup nair
Nov 22 '18 at 11:33
@Chris Even after commenting the query.addNonFetchJoin() line, still getting the below exception: org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "T1"."EID": invalid identifier. The malformed query still is: 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')); Don't understand why EMPLOYEE t1 not appended after PERSON t0 and before JOIN keyword in the query. Is it an issue with descriptor or expression?
– anup nair
Nov 22 '18 at 11:33
First, EID isn't the primary key in Employee/Person which confuses things slightly for EclipseLink, but it should be able to handle it. It seems you are hitting an issue with optimization logic which thinks that Employee table doesn't matter, which is incorrect for your mapping setup to a non-pk field. I haven't dealt with the native descriptor logic in quite a few years, but I'm sure there is a setting somewhere to fix this, it just will take some effort to track down on the inheritance policy class.
– Chris
Nov 22 '18 at 15:57
First, EID isn't the primary key in Employee/Person which confuses things slightly for EclipseLink, but it should be able to handle it. It seems you are hitting an issue with optimization logic which thinks that Employee table doesn't matter, which is incorrect for your mapping setup to a non-pk field. I haven't dealt with the native descriptor logic in quite a few years, but I'm sure there is a setting somewhere to fix this, it just will take some effort to track down on the inheritance policy class.
– Chris
Nov 22 '18 at 15:57
@Chris do you think adding descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") to employee descriptor configuration would resolve this as it's primay key of EMPLOYEE table and foreign key in Address table?
– anup nair
Nov 23 '18 at 4:41
@Chris do you think adding descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") to employee descriptor configuration would resolve this as it's primay key of EMPLOYEE table and foreign key in Address table?
– anup nair
Nov 23 '18 at 4:41
@Chris I added descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") in buildEmployeeDescriptor() method but still getting same malformed query. Any clue?
– anup nair
Nov 23 '18 at 13:03
@Chris I added descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") in buildEmployeeDescriptor() method but still getting same malformed query. Any clue?
– anup nair
Nov 23 '18 at 13:03
|
show 1 more comment
1 Answer
1
active
oldest
votes
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 reffered (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 addres
. 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 addres
. It helps. But maybe this is not what you need.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419566%2feclipselink-inheritance-policy-causing-malformed-query%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 reffered (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 addres
. 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 addres
. It helps. But maybe this is not what you need.
add a comment |
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 reffered (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 addres
. 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 addres
. It helps. But maybe this is not what you need.
add a comment |
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 reffered (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 addres
. 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 addres
. It helps. But maybe this is not what you need.
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 reffered (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 addres
. 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 addres
. It helps. But maybe this is not what you need.
answered Dec 14 '18 at 10:44
Anatoly SamoylenkoAnatoly Samoylenko
42137
42137
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419566%2feclipselink-inheritance-policy-causing-malformed-query%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Why are you using "query.addNonFetchJoin(employee.leftJoin(address, address.get("employeeId")));" at all? Try removing it and show the SQL as it is just duplicating what you already added with the employee.getAllowingNull("address") calls.
– Chris
Nov 22 '18 at 4:05
@Chris Even after commenting the query.addNonFetchJoin() line, still getting the below exception: org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "T1"."EID": invalid identifier. The malformed query still is: 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')); Don't understand why EMPLOYEE t1 not appended after PERSON t0 and before JOIN keyword in the query. Is it an issue with descriptor or expression?
– anup nair
Nov 22 '18 at 11:33
First, EID isn't the primary key in Employee/Person which confuses things slightly for EclipseLink, but it should be able to handle it. It seems you are hitting an issue with optimization logic which thinks that Employee table doesn't matter, which is incorrect for your mapping setup to a non-pk field. I haven't dealt with the native descriptor logic in quite a few years, but I'm sure there is a setting somewhere to fix this, it just will take some effort to track down on the inheritance policy class.
– Chris
Nov 22 '18 at 15:57
@Chris do you think adding descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") to employee descriptor configuration would resolve this as it's primay key of EMPLOYEE table and foreign key in Address table?
– anup nair
Nov 23 '18 at 4:41
@Chris I added descriptor.addPrimaryKeyFieldName("EMPLOYEE.EID") in buildEmployeeDescriptor() method but still getting same malformed query. Any clue?
– anup nair
Nov 23 '18 at 13:03