Consider the following Model
IPSubnet is a sub class of NetworkAddressBlock
We are trying to Bulk Delete IPSubnet with the following code
cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
CriteriaDelete<IPSubnetDAO> subnetDelete = cb.createCriteriaDelete(IPSubnetDAO.class);
Root subnetRoot = subnetDelete.from(IPSubnetDAO.class);
subnetDelete.where(cb.greaterThanOrEqualTo(subnetRoot.get(IPSubnetDAO._numericLowerAddress.getFieldName()),
net.getNumericLowerAddress()),
cb.lessThanOrEqualTo(subnetRoot.get(IPSubnetDAO._numericUpperAddress.getFieldName()),
net.getNumericLowerAddress()),
cb.or(cb.equal(subnetRoot.get(IPSubnetDAO._rootParentBlock.getFieldName()).get(IPSubnetDAO._ipAddressDomain.getFieldName()),
net.getIpAddressDomain()),
cb.equal(subnetRoot.get(IPSubnetDAO._ipAddressDomain.getFieldName()),
net.getIpAddressDomain())));
The following queries were generated
DELETE FROM IPSubnet WHERE EXISTS(SELECT
t0.ENTITYID FROM IPSubnet t3, NetworkAddressBlock t2, IPSubnet t1,
NetworkAddressBlock t0 WHERE (((((t1.NUMERICLOWERADDRESS >= ?) AND
(t1.NUMERICUPPERADDRESS <= ?)) AND ((t3.IPADDRESSDOMAIN = ?) OR
(t1.IPADDRESSDOMAIN = ?))) AND ((t1.ENTITYID = t0.ENTITYID) AND
(t0.ENTITYCLASS = ?))) AND ((t2.ENTITYID = t1.ROOTPARENTBLOCK) AND
((t3.ENTITYID = t2.ENTITYID) AND (t2.ENTITYCLASS = ?)))) AND t1.ENTITYID
= IPSubnet.ENTITYID)
bind => [369098752, 385875967, 150000, 150000, IPSubnetDAO, IPSubnetDAO]
DELETE
FROM NetworkAddressBlock WHERE (ENTITYCLASS = ?) AND NOT EXISTS(SELECT
t0.ENTITYID FROM NetworkAddressBlock t0, IPSubnet t1 WHERE (t1.ENTITYID =
t0.ENTITYID) AND t0.ENTITYID = NetworkAddressBlock.ENTITYID)
bind => [IPSubnetDAO]
The second query is very inefficient and has bad explain plan (involves Full Table Scan). My question is why is NOT Eclipselink applying the same criteria that it applied to child table to the parent table as well? Why is it trying to generate a different query that looks at all NetworkAddressBlock entries that does NOT exist in child table?
We have huge number of records in this table and is taking lot of time for the second query.
Is there a way to customize this behavior and generate the same query for parent table as well?
Thanks,
Rama