[Fix] Fixed bug where changed element is not returned in streams
This commit is contained in:
parent
acf3b3ff6c
commit
bbf021f73b
|
@ -514,17 +514,29 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<Resource> streamResources(String... types) {
|
public Stream<Resource> streamResources(String... types) {
|
||||||
return getResourceMap().stream(this, types);
|
return getResourceMap().stream(this, types).map(e -> {
|
||||||
|
// perhaps the element was changed before, so we check if it is in the filter first
|
||||||
|
Resource element = getElementFromFilter(Tags.RESOURCE, e.getLocator());
|
||||||
|
return element == null ? e : element;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<Order> streamOrders(String... types) {
|
public Stream<Order> streamOrders(String... types) {
|
||||||
return getOrderMap().stream(this, types);
|
return getOrderMap().stream(this, types).map(e -> {
|
||||||
|
// perhaps the element was changed before, so we check if it is in the filter first
|
||||||
|
Order element = getElementFromFilter(Tags.ORDER, e.getLocator());
|
||||||
|
return element == null ? e : element;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<Activity> streamActivities(String... types) {
|
public Stream<Activity> streamActivities(String... types) {
|
||||||
return getActivityMap().stream(this, types);
|
return getActivityMap().stream(this, types).map(e -> {
|
||||||
|
// perhaps the element was changed before, so we check if it is in the filter first
|
||||||
|
Activity element = getElementFromFilter(Tags.ACTIVITY, e.getLocator());
|
||||||
|
return element == null ? e : element;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -276,7 +276,7 @@ public class StrolchSearchTest {
|
||||||
|
|
||||||
Map<String, State> states = new ActivitySearch()
|
Map<String, State> states = new ActivitySearch()
|
||||||
|
|
||||||
.types().where(state().isEqualTo(State.PLANNING).and(name(isEqualTo("Activity"))).asActivityExp())
|
.types().where(state().isEqualTo(State.PLANNING).and(name(isEqualTo("Activity"))).asActivity())
|
||||||
|
|
||||||
.search(tx).toMap(Activity::getId, Activity::getState);
|
.search(tx).toMap(Activity::getId, Activity::getState);
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ public class Order extends AbstractStrolchRootElement implements StrolchRootElem
|
||||||
|
|
||||||
private static final long serialVersionUID = 0L;
|
private static final long serialVersionUID = 0L;
|
||||||
|
|
||||||
|
protected Locator locator;
|
||||||
protected Version version;
|
protected Version version;
|
||||||
protected Date date;
|
protected Date date;
|
||||||
protected State state;
|
protected State state;
|
||||||
|
@ -204,9 +205,12 @@ public class Order extends AbstractStrolchRootElement implements StrolchRootElem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Locator getLocator() {
|
public Locator getLocator() {
|
||||||
LocatorBuilder lb = new LocatorBuilder();
|
if (this.locator == null) {
|
||||||
fillLocator(lb);
|
LocatorBuilder lb = new LocatorBuilder();
|
||||||
return lb.build();
|
fillLocator(lb);
|
||||||
|
this.locator = lb.build();
|
||||||
|
}
|
||||||
|
return this.locator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -41,6 +41,7 @@ public class Resource extends AbstractStrolchRootElement implements StrolchRootE
|
||||||
|
|
||||||
private static final long serialVersionUID = 0L;
|
private static final long serialVersionUID = 0L;
|
||||||
|
|
||||||
|
protected Locator locator;
|
||||||
protected Version version;
|
protected Version version;
|
||||||
protected Map<String, StrolchTimedState<IValue<?>>> timedStateMap;
|
protected Map<String, StrolchTimedState<IValue<?>>> timedStateMap;
|
||||||
protected PolicyDefs policyDefs;
|
protected PolicyDefs policyDefs;
|
||||||
|
@ -240,9 +241,12 @@ public class Resource extends AbstractStrolchRootElement implements StrolchRootE
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Locator getLocator() {
|
public Locator getLocator() {
|
||||||
LocatorBuilder lb = new LocatorBuilder();
|
if (this.locator == null) {
|
||||||
fillLocator(lb);
|
LocatorBuilder lb = new LocatorBuilder();
|
||||||
return lb.build();
|
fillLocator(lb);
|
||||||
|
this.locator = lb.build();
|
||||||
|
}
|
||||||
|
return this.locator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -42,7 +42,8 @@ public class Activity extends AbstractStrolchRootElement
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private Version version;
|
protected Locator locator;
|
||||||
|
protected Version version;
|
||||||
|
|
||||||
protected Activity parent;
|
protected Activity parent;
|
||||||
protected TimeOrdering timeOrdering;
|
protected TimeOrdering timeOrdering;
|
||||||
|
@ -453,9 +454,12 @@ public class Activity extends AbstractStrolchRootElement
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Locator getLocator() {
|
public Locator getLocator() {
|
||||||
LocatorBuilder lb = new LocatorBuilder();
|
if (this.locator == null) {
|
||||||
fillLocator(lb);
|
LocatorBuilder lb = new LocatorBuilder();
|
||||||
return lb.build();
|
fillLocator(lb);
|
||||||
|
this.locator = lb.build();
|
||||||
|
}
|
||||||
|
return this.locator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package li.strolch.service;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import li.strolch.model.ModelGenerator;
|
||||||
|
import li.strolch.model.Resource;
|
||||||
|
import li.strolch.persistence.api.AddResourceCommand;
|
||||||
|
import li.strolch.persistence.api.RemoveResourceCommand;
|
||||||
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
import li.strolch.persistence.api.UpdateResourceCommand;
|
||||||
|
import li.strolch.search.ResourceSearch;
|
||||||
|
import li.strolch.service.api.AbstractService;
|
||||||
|
import li.strolch.service.api.Service;
|
||||||
|
import li.strolch.service.api.ServiceArgument;
|
||||||
|
import li.strolch.service.api.ServiceResult;
|
||||||
|
import li.strolch.service.test.AbstractRealmServiceTest;
|
||||||
|
import li.strolch.utils.dbc.DBC;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class TxModifyTest extends AbstractRealmServiceTest<ServiceArgument, ServiceResult> {
|
||||||
|
|
||||||
|
private Class<? extends Service<ServiceArgument, ServiceResult>> svcClass;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFindModifiedElementInSearch() {
|
||||||
|
this.svcClass = ModifyAndSearchService.class;
|
||||||
|
runServiceInAllRealmTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRollbackSuccessfully() {
|
||||||
|
this.svcClass = RollbackService.class;
|
||||||
|
runServiceInAllRealmTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<? extends Service<ServiceArgument, ServiceResult>> getSvcClass() {
|
||||||
|
return this.svcClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceArgument getArgInstance() {
|
||||||
|
return new ServiceArgument();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ModifyAndSearchService extends AbstractService<ServiceArgument, ServiceResult> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult getResultInstance() {
|
||||||
|
return new ServiceResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServiceArgument getArgumentInstance() {
|
||||||
|
return new ServiceArgument();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult internalDoService(ServiceArgument arg) throws Exception {
|
||||||
|
|
||||||
|
String type = "Car";
|
||||||
|
String id = "car001";
|
||||||
|
Resource resource = ModelGenerator.createResource(id, id, type);
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
tx.add(resource);
|
||||||
|
tx.commitOnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
|
||||||
|
// get the element
|
||||||
|
Resource car001 = tx.getResourceBy(type, id, true);
|
||||||
|
|
||||||
|
// modify
|
||||||
|
car001.setName("Changed!");
|
||||||
|
tx.update(car001);
|
||||||
|
|
||||||
|
// search for all cars
|
||||||
|
List<Resource> cars = new ResourceSearch().types(type).search(tx).cloneIfReadOnly().toList();
|
||||||
|
assertEquals(1, cars.size());
|
||||||
|
assertSame("We didn't get the same car!", car001, cars.get(0));
|
||||||
|
|
||||||
|
// also validate get returns the same instance
|
||||||
|
Resource carByGet = tx.getResourceBy(type, id, true);
|
||||||
|
assertSame("We didn't get the same car!", car001, carByGet);
|
||||||
|
|
||||||
|
// also validate find returns the same instance
|
||||||
|
Resource carByFind = tx.findElement(car001.getLocator());
|
||||||
|
assertSame("We didn't get the same car!", car001, carByFind);
|
||||||
|
|
||||||
|
tx.commitOnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ServiceResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RollbackService extends AbstractService<ServiceArgument, ServiceResult> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult getResultInstance() {
|
||||||
|
return new ServiceResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServiceArgument getArgumentInstance() {
|
||||||
|
return new ServiceArgument();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult internalDoService(ServiceArgument arg) throws Exception {
|
||||||
|
|
||||||
|
String type = "Car";
|
||||||
|
String id = "car002";
|
||||||
|
Resource resource = ModelGenerator.createResource(id, id, type);
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
tx.add(resource);
|
||||||
|
tx.commitOnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
Resource car001 = tx.getResourceBy(type, id, true);
|
||||||
|
|
||||||
|
// modify
|
||||||
|
car001.setName("Changed!");
|
||||||
|
tx.update(car001);
|
||||||
|
|
||||||
|
tx.rollbackOnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// now make sure the element was not changed
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
Resource car001 = tx.getResourceBy(type, id, true);
|
||||||
|
assertEquals("Expected name not to be changed in rollback of TX!", id, car001.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ServiceResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue