Issue Details (XML | Word | Printable)

Key: NUCAPIJDO-77
Type: Bug Bug
Status: Closed Closed
Resolution: Duplicate
Priority: Testcase Required Testcase Required
Assignee: Unassigned
Reporter: jonas
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
DataNucleus API JDO

Using java 8 stream api on Sets results in undefined behaviour

Created: 18/Jun/14 06:07 PM   Updated: 23/Jul/14 12:14 PM   Resolved: 19/Jun/14 08:25 AM
Component/s: None
Affects Version/s: 4.0.0.m3
Fix Version/s: None

Environment: jdk1.8.0_05.jdk, linux

Datastore: MySQL
Severity: Test/Acceptance


 Description  « Hide
The new collections api in java 8 has a nice stream api. However using it with objects managed by a percistencemanager in jdo results in undefined behaviour.

Here are some results from live debugging:
new HashSet(market.getSelections()).stream().count();
and market.getSelections().size();
returns (long) 3

market.getSelections().stream().count();
returns (long) 0




Andy Jefferson made changes - 18/Jun/14 06:32 PM
Field Original Value New Value
Priority Major [ 3 ] No Testcase [ 6 ]
jonas added a comment - 18/Jun/14 11:38 PM - edited
I'd just like to add:
The class that was used is org.datanucleus.store.types.wrappers.backed.HashSet

It's hard to reproduce since it depends what's loaded already in memory. I have not been able to create a simple test case for this, it occurs depending on what's loaded in the hashset internal cache

This affects all stream operations like forEach etc

Andy Jefferson added a comment - 19/Jun/14 08:25 AM
Perhaps you mean http://www.datanucleus.org/servlet/jira/browse/NUCJAVAEIGHT-14

Doing a Collection.stream() relies on a new Java 8 method (on Collection) and that is obviously not defined in datanucleus-core (which builds/runs with Java 7). Besides which doing
dn_coll.stream().count()
would be an inefficient operation since dn_coll.size() simply does a COUNT query in the database now when elements not loaded), and size of the internal delegate if elements are loaded - hence you won't beat that either way.


Anybody could contribute such wrapper classes with stream() and striterator() defined, for inclusion in the Java8 plugin, and then add an entry like this in plugin.xml

<java-type name="java.util.ArrayList" wrapper-type="org.datanucleus.store.types.java8.wrappers.ArrayList"
            wrapper-type-backed="org.datanucleus.store.types.java8.wrappers.backed.ArrayList" priority="1"/>

The key there is the "priority" which means it will then override the default version in datanucleus-core. Though clearly "stream" is much more than count() and allowing use of stream() on an internal proxy class implies querying in the database for that filter etc, hence opens a large bag rather than just one method.

Not a priority here. Awaiting your contribution.

Andy Jefferson made changes - 19/Jun/14 08:25 AM
Status Open [ 1 ] Resolved [ 5 ]
Resolution Duplicate [ 3 ]
jonas added a comment - 19/Jun/14 09:39 AM
Thanks, the problem was that it resulted in undefined behaviour and the error was hard to track down.
I'm of course not using count(), it was a way to display the problem.

Im currently wrapping all the stream operations in a new HashSet just to make sure now, the performance overhead is not that great since all objects needs to be fetched any ways.

Andy Jefferson made changes - 23/Jul/14 12:14 PM
Status Resolved [ 5 ] Closed [ 6 ]