Today I was using the CategoryLookup droplet to find a category’s child products. However when I accessed the child products I would get this JDBC error.
java.lang.NullPointerException
at java.lang.String.(String.java:166)
at oracle.sql.CharacterSet.AL32UTF8ToString(CharacterSet.java:1517)
I realized my product data was corrupted. However this category had over 70 child products. The stack trace wasn’t telling me which one was corrupt and going through each child product to find out which one was corrupt was too painful.
I first queried the database to find all the child product ID’s.
SQL> select child_prd_id from dcs_cat_chldprd where category_id='cat101' order by sequence_num;
I then created a simple JHTML page which would query each child product and output which ones were corrupted.
<java>
final String [] product_ids = { "prod101", "prod102", "prod103" };
for (int ii = 0; ii < product_ids.length; ii++) {
out.print(ii + ". [" + product_ids[ii] + "] ");
try {
</java>
<droplet name="/atg/commerce/catalog/ProductLookup">
<param name="id" value="`product_ids[ii]`">
<oparam name="output">
<valueof param="element.displayName"/><br/>
</oparam>
</droplet>
<java>
} catch (RuntimeException exc) {
out.println(exc + "<br>");
}
}
</java>
Once I knew which child products were bad I removed their mappings to the category in dcs_cat_chldprd.
SQL> delete from dcs_cat_childprd where child_prd_id = 'prod102' and category_id='cat101';
Then I updated the sequence numbers so that they are all consecutive by moving the ones at the end to fill the holes created by the previous deletes.
SQL> update dcs_cat_childprd set sequence_num = 1 where child_prd_id = 'prod103' and category_id='cat101';