[rules-users] ConcurrentModificationException loading facts from db (Hibernate).

Wolfgang Laun wolfgang.laun at gmail.com
Tue Jul 3 10:34:28 EDT 2012


$unitPrices : ArrayList() is bound to a collected list. The first insertion of
a fact from this list cancels the activation and results in this ArrayList
becoming modified.

Copy the List before iterating over it, e.g.

    ArrayList copiedList = new ArrayList( $unitPrices );
    for( Pricelist  priceList : (List<Pricelist>)copiedList ) {
 			insert (priceList);
   }

-W


On 03/07/2012, groovenarula <gnarula1 at la-z-boy.com> wrote:
> In my use case, I have ~ 200,000 rows in a table that I need lookup in
> order
> to price an item. Rather than load the entire table into working memory,I'm
> trying load the relevant rows (based on a matching criteria) and load those
> as facts and then have my rules evaluate the loaded facts. Based on that
> I've got the following rule :
>
> rule "Load pricelist"
> 	salience 10000
> 	when
> 		
> 		$priceUnit : PriceUnit()
> 		not ( exists Pricelist( id.prodid == $priceUnit.prodid ) )
> 		$unitPrices : ArrayList() from collect ( Pricelist() from
> PricelistUtilities.getPriceLists($priceUnit.prodid) )
> 	then
> 		for( Pricelist  priceList : (List<Pricelist>) $unitPrices ) {
> 			insert (priceList);
> 		}
> end
>
> In the rule above - 'PriceUnit' is the unit that I'm trying to price. And
> 'Pricelist' is the facts that I'm trying to fetch from a table based on the
> prodid matching and inserting those into WM. The
> PricelistUtilities.getPriceList returns a list of price list items that
> match the 'Product id' (prodid). In the RHS, all I'm trying to iterate over
> the list of pricelists and then insert those into WM.
>
> When I execute the rule above, I can see that the rule is executing the
> 'select' to load pricelists :
>
> Hibernate:
>     /*
> from
>     PriceList
> where
>     status = 'A'
>     and end_date >= current_date
>     and prodid = '010366'
>     and cover_grade = 'LF' */ select
>         pricelist0_.prodid as prodid1_,
>         pricelist0_.cover_grade as cover2_1_,
>         pricelist0_.cover_series as cover3_1_,
>         pricelist0_.cover_color as cover4_1_,
>         pricelist0_.division as division1_,
>         pricelist0_.location as location1_,
>         pricelist0_.list as list1_,
>         pricelist0_.start_date as start8_1_,
>         pricelist0_.end_date as end9_1_,
>         pricelist0_.timestamp as timestamp1_,
>         pricelist0_.status as status1_,
>         pricelist0_.sold_flag as sold12_1_,
>         pricelist0_.base_price as base13_1_,
>         pricelist0_.list_price as list14_1_,
>         pricelist0_.add_on as add15_1_,
>         pricelist0_.landed_frt as landed16_1_
>     from
>         catalog.pricelist pricelist0_
>     where
>         pricelist0_.status='A'
>         and end_date>=current_date
>         and prodid='123456'
>
> However, I get an java.util.ConcurrentModificationException when the rule
> fires :
>
> org.drools.runtime.rule.ConsequenceException: rule: Load pricelist
>
> 	at
> org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39)
> 	at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1101)
> 	at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1029)
> 	at org.drools.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1251)
> 	at
> org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:737)
> 	at
> org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:701)
> 	at
> org.drools.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:218)
> 	at com.generic.rules.utils.DroolsTest.main(DroolsTest.java:46)
> Caused by: java.util.ConcurrentModificationException
> 	at
> java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
> 	at java.util.AbstractList$Itr.next(AbstractList.java:343)
> 	at
> com.sample.Rule_Load_pricelist_0.defaultConsequence(Rule_Load_pricelist_0.java:7)
> 	at
> com.sample.Rule_Load_pricelist_0DefaultConsequenceInvoker.evaluate(Rule_Load_pricelist_0DefaultConsequenceInvoker.java:27)
> 	at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1091)
> 	... 6 more
>
> If I comment the check for existing PriceList Items 'not ( exists
> Pricelist(
> id.prodid == $priceUnit.prodid ) )', then it works fine. But as soon as I
> add the check back, it breaks.
>
> Is this a bug or am I doing something wrong ?
>
> Any help / insight will be appreciated.
>
> Thanks in advance.
>
> --
> View this message in context:
> http://drools.46999.n3.nabble.com/ConcurrentModificationException-loading-facts-from-db-Hibernate-tp4018431.html
> Sent from the Drools: User forum mailing list archive at Nabble.com.
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>


More information about the rules-users mailing list