[ https://issues.apache.org/jira/browse/OPENJPA-2557?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Heath Thomann updated OPENJPA-2557: ----------------------------------- Attachment: OPENJPA-2557-2.1.x.patch > FinderCache contains incorrectly cached query with a NULL for a Primary Key. > ---------------------------------------------------------------------------- > > Key: OPENJPA-2557 > URL: https://issues.apache.org/jira/browse/OPENJPA-2557 > Project: OpenJPA > Issue Type: Bug > Components: query > Affects Versions: 2.1.2, 2.2.2, 2.2.1.1, 2.3.1, 2.4.0 > Reporter: Heath Thomann > Priority: Critical > Attachments: OPENJPA-2557-2.1.x.patch > > > Take the following SQL from a finder: > SELECT t1.code, t1.EXTDISCR, t0.field1, t0.field2 FROM TB1 t0 LEFT OUTER JOIN > AbstractExtValue t1 ON t0.EXT_USR = t1.code WHERE (t1.EXTDISCR IS NULL OR > t1.EXTDISCR IN (?)) AND t0.field1 = ? AND t0.field2 IS NULL > Notice the 't0.field2 IS NULL' part. Field2 is part of a compound PK of > table 'TB1', where the compound PK consists of two fields (field1 and > field2). This will become more apparent when looking at the attached test. > Because the PK field 'IS NULL', this finder query should NOT be added to the > FinderQuery cache (i.e. we can't cache something which is "hard coded" to 'IS > NULL'....in the case where field2 is non-null, the query will never account > for that). However, this query is in fact incorrectly added to the cache. > To understand why this is incorrectly added we must look at two things. > First, if we look at the attached test, we can see that the test uses > inheritance and a discriminator value. In the above SQL the 't1.EXTDISCR' is > the discriminator value. As you can see we are selecting field1 and field2, > where field2 IS NULL. Second, we have to look at the OpenJPA code where we > determine if the finder query can be cached. That is, look here in > FinderQueryImpl: > static FinderQueryImpl newFinder(ClassMapping mapping, > SelectExecutor select) { > SelectImpl impl = extractImplementation(select); > if (impl == null) > return null; > SQLBuffer buffer = impl.getSQL(); > Column[] pkCols = mapping.getPrimaryKeyColumns(); > boolean canCache = pkCols.length == buffer.getParameters().size(); > As you can see, the last line determines if the query can be cached (i.e. > 'canCache'). In this case, OpenJPA compares the pkCols (PK columns) to the > parameters. In most cases, these two should be equal for a finder query. > However, at least in the case where a discriminator is used, the finder will > have one extra more parameter in the finder query. In those cases, the > 'canCache' will be false and the query not cached. However, take the case > where one of the compound PKs contains 'IS NULL' (see above SQL at the start > of this text). In this case, 'pkCols.length' will be two, AND the params > will be two. So by the 'canCache' test, it will be true. However, in this > case we should not cache the above query (i.e. in so doing field2 will always > be "NULL"). > To resolve this issue, I feel that we need to make sure the the columns in > the 'buffer' exactly match that of pkCols. See the attached test/patch for > proposed fix. > Thanks, > Heath Thomann -- This message was sent by Atlassian JIRA (v6.3.4#6332)