Re: ObjectSelect to select uncommitted objects

Andrus Adamchik <[email protected]>
Newsgroups gmane.comp.java.cayenne.user
Message-ID <[email protected]>
FWIW, there were requests for this functionality previously, but it was hard to achieve full feature parity between in-memory and DB evaluation, so we didn't do it yet. Perhaps we should do it incrementally over time, addressing various edge cases as we uncover them.

Andrus


> On Nov 16, 2020, at 11:29 PM, [email protected] wrote:
> 
> Thanks!!
> 
> I need to look carefully into this code, but it looks very promising.
> 
> Cheers,
> 
> Giulio Cesare
> 
> 
> On Mon, Nov 16, 2020 at 7:53 PM John Huss <[email protected]> wrote:
> 
>> There isn't anything built-in. I use this method in my own DataContext
>> subclass to do it. Use at your own risk, etc.
>> 
>> *public* <T *extends* Persistent> List<T>
>> selectIncludingPendingChanges(ObjectSelect<T> query) {
>> 
>> Set<Object> newAndModified = *new* HashSet<>(newObjects());
>> 
>> newAndModified.addAll(modifiedObjects());
>> 
>> Set<T> inMemoryResults = newAndModified.stream()
>> 
>> .filter(o -> o.getClass().equals(query.getEntityType()))
>> 
>> .filter(o -> query.getWhere().match(o))
>> 
>> .map(o -> (T)o)
>> 
>> .collect(Collectors.*toSet*());
>> 
>> List<T> dbResults = select(query);
>> 
>> dbResults.removeAll(newAndModified); // these have already been checked
>> 
>> dbResults.removeAll(deletedObjects());
>> 
>> *if* (inMemoryResults.isEmpty()) {
>> 
>> *return* dbResults; // performance optimization
>> 
>> }
>> 
>> inMemoryResults.addAll(dbResults); // combines and removes duplicates
>> 
>> List<T> results = *new* ArrayList<>(inMemoryResults);
>> 
>> *if* (query.getOrderings() != *null* && !query.getOrderings().isEmpty()) {
>> 
>> Ordering.*orderList*(results, *new* ArrayList<>(query.getOrderings()));
>> 
>> }
>> 
>> *if* (query.getLimit() > 0) {
>> 
>> results = results.subList(0, query.getLimit());
>> 
>> }
>> 
>> *return* (List<T>) results;
>> 
>> }
>> 
>> 
>> *public* *static* *class* Factory *extends* DataContextFactory {
>> 
>> @Override
>> 
>> *protected* MyDataContext newInstance(DataChannel parent, ObjectStore
>> objectStore) {
>> 
>> *return* *new* MyDataContext(parent, objectStore);
>> 
>> }
>> 
>> }
>> 
>> 
>> *public* *static* *final* Module *MODULE* = binder ->
>> 
>> 
>> binder.bind(ObjectContextFactory.*class*).to(MyDataContext.Factory.*class*);
>> 
>> 
>> 
>> On Sat, Nov 14, 2020 at 10:20 AM [email protected] <
>> [email protected]> wrote:
>> 
>>> Hello,
>>> 
>>> I have multiple places where I have to search data either on the current
>>> ObjectStore (newly inserted or modified objects) or directly in the DB.
>>> 
>>> At the moment I have two distinct blocks of code, one expressed as a
>>> Predicate (used inside a stream filter) and the other with an
>> ObjectSelect
>>> (on which I call its select method).
>>> 
>>> As both structure encode the same "logic" criteria, it would be nice to
>> be
>>> able to derive one from the other.
>>> 
>>> One way to solve this would be to be able to transform on ObjectSelect
>>> instance into a Predicate instance.
>>> Or, the ability to run an ObjectSelect not only on the DB, but also into
>>> the uncommitted objects in the ObjectContext.
>>> 
>>> Is there anything I am missing that could help me dealing with this need?
>>> 
>>> Cheers,
>>> 
>>> Giulio Cesare
>>> 
>>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.