Threading Problem (maybe with Criteria)

#1

Hi all

I found some threading problems I do not understand:

After creating some testobjects (i.e. 100000) the test opens the Database, start some queries with criteria in several threads (maybe 10) and close the Database. Each thread creates its own EntityManager, wich will be closed at the end of the thread. This procedure will be repeated several times. After a while of running there occur two kinds of errors in some threads, but there is no regularity.

1. The first one one is a 'ConcurrentModificationException'. It seems that the map received by getAttrMap() is not thread safe (as would a ConcurrentLinkedHashMap).

FETCH thread nr (36) count: 982 UIDs in 26 msek
FETCH thread nr (41) count: 982 UIDs in 29 msek
FETCH thread nr (44) count: 982 UIDs in 14 msek
FETCH thread nr (39) count: 982 UIDs in 25 msek
FETCH thread nr (42) count: 982 UIDs in 31 msek
FETCH thread nr (40) count: 982 UIDs in 23 msek
FETCH thread nr (37) count: 982 UIDs in 32 msek
FETCH thread nr (43) count: 982 UIDs in 32 msek
FETCH thread nr (35) count: 982 UIDs in 33 msek
FETCH thread nr (38) count: 982 UIDs in 32 msek
Exception in thread "Thread-2" java.util.ConcurrentModificationException
at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:394)
at java.util.LinkedHashMap$EntryIterator.next(LinkedHashMap.java:413)
at java.util.LinkedHashMap$EntryIterator.next(LinkedHashMap.java:412)
at java.util.HashMap.putAll(HashMap.java:621)
at com.objectdb.jpa.type.ManagedTypeImpl.getAttrMap(ManagedTypeImpl.java:156)
at com.objectdb.jpa.type.ManagedTypeImpl.getAttribute(ManagedTypeImpl.java:199)
at com.objectdb.jpa.criteria.PathImpl.get(PathImpl.java:114)
at com.objectdb.test.ObjectDBTest$2.RunOneTest(ObjectDBTest.java:160)
at com.objectdb.test.ObjectDBTest$2.run(ObjectDBTest.java:149)
at java.lang.Thread.run(Thread.java:722)


2. The second one is an 'IllegalArgumentException' it seems, that the attribute 'm_age' was not found (of course it was some 60 threads before)

FETCH thread nr (57) count: 982 UIDs in 31 msek
FETCH thread nr (61) count: 982 UIDs in 18 msek
FETCH thread nr (58) count: 982 UIDs in 29 msek
FETCH thread nr (59) count: 982 UIDs in 26 msek
FETCH thread nr (66) count: 982 UIDs in 15 msek
FETCH thread nr (63) count: 982 UIDs in 20 msek
FETCH thread nr (64) count: 982 UIDs in 19 msek
FETCH thread nr (65) count: 982 UIDs in 18 msek
FETCH thread nr (62) count: 982 UIDs in 25 msek
FETCH thread nr (60) count: 982 UIDs in 27 msek
Exception in thread "Thread-10" [ObjectDB 2.5.1_04] java.lang.IllegalArgumentException
Attribute m_age is not found in type com.objectdb.test.PersonTest (error 385)
at com.objectdb.jpa.type.ManagedTypeImpl.getAttribute0(ManagedTypeImpl.java:650)
at com.objectdb.jpa.type.ManagedTypeImpl.getAttribute(ManagedTypeImpl.java:199)
at com.objectdb.jpa.criteria.PathImpl.get(PathImpl.java:114)
at com.objectdb.test.ObjectDBTest$2.RunOneTest(ObjectDBTest.java:161)
at com.objectdb.test.ObjectDBTest$2.run(ObjectDBTest.java:149)
at java.lang.Thread.run(Thread.java:722)

More testobjects in the database will result in earlier and more exception.

objectdb.conf was configured

<processing cache="64mb" max-threads="10" />

but the number of threads doesn't really change the result

I'm new to JPA, so maybe there is something I miss?

best regards
Arne

----
Mac OSX - 10.8
2.4 GHz Intel core dual
8 GB DDR3
250 GB Samsung SSD 840 Series Media

#2

No error using SQL String statement

TypedQuery<AdvoluxUID> query= manager.createQuery("SELECT NEW AdvoluxUID(p.m_uid,p.m_udb) FROM PersonTest p WHERE m_age=50", AdvoluxUID.class);

instead of Criteria API

CriteriaBuilder cbuilder = manager.getCriteriaBuilder();
CriteriaQuery<AdvoluxUID> cquery = cbuilder.createQuery(AdvoluxUID.class);
Root<PersonTest> person = cquery.from(PersonTest.class);
   
cquery.select(cbuilder.construct(AdvoluxUID.class,person.get("m_uid"),person.get("m_udb")));
cquery.where(cbuilder.equal(person.<Integer>get("m_age"), 50));
   
TypedQuery<AdvoluxUID> query= manager.createQuery(cquery);

best regards

Arne

#3

Thank you for this report. It seems that a synchronization was missing in the implementation of the JPA metamodel API.

Please try build 2.5.2_02 that will hopefully fix this issue.

Unfortunately we couldn't verify it by running your test because the classes StringHelper and LogHelper are missing (following the posting instructions with test cases would be much appreciated).

ObjectDB Support
#4

Thank you for quick response

Sorry I missed to remove this classes, the testcase (testcase 27.08.13) now doesn't use any of our classes. 

Unfortunatly even the 2.5.2_02 produces some 'IllegalArgumentException' (from what it seems later than with 2.5.2

FETCH thread nr (259) count: 967 UIDs in 1 msek
FETCH thread nr (261) count: 967 UIDs in 1 msek
FETCH thread nr (260) count: 967 UIDs in 2 msek
FETCH thread nr (262) count: 967 UIDs in 1 msek
FETCH thread nr (263) count: 967 UIDs in 1 msek
FETCH thread nr (264) count: 967 UIDs in 2 msek
Exception in thread "Thread-227" [ObjectDB 2.5.2_02] java.lang.IllegalArgumentException
Attribute m_age is not found in type com.objectdb.test.PersonTest (error 385)
at com.objectdb.jpa.type.ManagedTypeImpl.getAttribute0(ManagedTypeImpl.java:650)
at com.objectdb.jpa.type.ManagedTypeImpl.getAttribute(ManagedTypeImpl.java:199)
at com.objectdb.jpa.criteria.PathImpl.get(PathImpl.java:114)
at com.objectdb.test.ObjectDBTest$3.RunOneTest(ObjectDBTest.java:200)
at com.objectdb.test.ObjectDBTest$3.run(ObjectDBTest.java:188)
at java.lang.Thread.run(Thread.java:722)

best regards

Arne

PS: I updated the testcase at the beginning of my post

#5

Thank you for the new test. We are working on a solution now.

ObjectDB Support
#6

Build 2.5.2_04 should fix the issue. Thanks again for your report.

ObjectDB Support
#7

build 2.5.2_04 works fine

thank you very much, best regards 

Arne

Reply