Fix misuse of Drafted interface in tests. WIP fixing use of immutable collections in UPDATE/draft logic.
This commit is contained in:
parent
33d2459538
commit
7a56059036
14 changed files with 96 additions and 101 deletions
|
@ -51,12 +51,7 @@ public abstract class AbstractEntityDraft<E> implements Drafted<E> {
|
||||||
} else {
|
} else {
|
||||||
// Collections fetched from the entityMap
|
// Collections fetched from the entityMap
|
||||||
if (value instanceof Collection) {
|
if (value instanceof Collection) {
|
||||||
try {
|
value = (T) SerializationUtils.<Serializable>clone((Serializable) value);
|
||||||
value = MappingUtil.<T>clone(value);
|
|
||||||
} catch (CloneNotSupportedException e) {
|
|
||||||
// TODO(gburd): deep?shallow? copy of List, Map, Set to a mutable collection.
|
|
||||||
value = (T) SerializationUtils.<Serializable>clone((Serializable) value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.collect.HashBasedTable;
|
import com.google.common.collect.HashBasedTable;
|
||||||
import com.google.common.collect.Table;
|
import com.google.common.collect.Table;
|
||||||
import com.google.common.collect.TreeTraverser;
|
import com.google.common.collect.TreeTraverser;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
@ -30,9 +31,9 @@ import net.helenus.core.cache.CacheUtil;
|
||||||
import net.helenus.core.cache.Facet;
|
import net.helenus.core.cache.Facet;
|
||||||
import net.helenus.core.operation.AbstractOperation;
|
import net.helenus.core.operation.AbstractOperation;
|
||||||
import net.helenus.core.operation.BatchOperation;
|
import net.helenus.core.operation.BatchOperation;
|
||||||
import net.helenus.core.reflect.Drafted;
|
|
||||||
import net.helenus.mapping.MappingUtil;
|
import net.helenus.mapping.MappingUtil;
|
||||||
import net.helenus.support.Either;
|
import net.helenus.support.Either;
|
||||||
|
import org.apache.commons.lang3.SerializationUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -218,15 +219,11 @@ public abstract class AbstractUnitOfWork<E extends Exception>
|
||||||
result = checkParentCache(facets);
|
result = checkParentCache(facets);
|
||||||
if (result.isPresent()) {
|
if (result.isPresent()) {
|
||||||
Object r = result.get();
|
Object r = result.get();
|
||||||
try {
|
Class<?> iface = MappingUtil.getMappingInterface(r);
|
||||||
Class<?> iface = MappingUtil.getMappingInterface(r);
|
if (Helenus.entity(iface).isDraftable()) {
|
||||||
if (Drafted.class.isAssignableFrom(iface)) {
|
cacheUpdate(r, facets);
|
||||||
cacheUpdate(r, facets);
|
} else {
|
||||||
} else {
|
cacheUpdate(SerializationUtils.<Serializable>clone((Serializable) r), facets);
|
||||||
cacheUpdate(MappingUtil.clone(r), facets);
|
|
||||||
}
|
|
||||||
} catch (CloneNotSupportedException e) {
|
|
||||||
result = Optional.empty();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -24,18 +24,20 @@ import com.google.common.base.Function;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CompletionException;
|
import java.util.concurrent.CompletionException;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import net.helenus.core.AbstractSessionOperations;
|
import net.helenus.core.AbstractSessionOperations;
|
||||||
|
import net.helenus.core.Helenus;
|
||||||
import net.helenus.core.UnitOfWork;
|
import net.helenus.core.UnitOfWork;
|
||||||
import net.helenus.core.cache.CacheUtil;
|
import net.helenus.core.cache.CacheUtil;
|
||||||
import net.helenus.core.cache.Facet;
|
import net.helenus.core.cache.Facet;
|
||||||
import net.helenus.core.reflect.Drafted;
|
|
||||||
import net.helenus.mapping.MappingUtil;
|
import net.helenus.mapping.MappingUtil;
|
||||||
import net.helenus.support.Fun;
|
import net.helenus.support.Fun;
|
||||||
|
import org.apache.commons.lang3.SerializationUtils;
|
||||||
|
|
||||||
public abstract class AbstractOptionalOperation<E, O extends AbstractOptionalOperation<E, O>>
|
public abstract class AbstractOptionalOperation<E, O extends AbstractOptionalOperation<E, O>>
|
||||||
extends AbstractStatementOperation<E, O> {
|
extends AbstractStatementOperation<E, O> {
|
||||||
|
@ -153,26 +155,22 @@ public abstract class AbstractOptionalOperation<E, O extends AbstractOptionalOpe
|
||||||
cachedResult = (E) sessionOps.checkCache(tableName, facets);
|
cachedResult = (E) sessionOps.checkCache(tableName, facets);
|
||||||
if (cachedResult != null) {
|
if (cachedResult != null) {
|
||||||
Class<?> iface = MappingUtil.getMappingInterface(cachedResult);
|
Class<?> iface = MappingUtil.getMappingInterface(cachedResult);
|
||||||
try {
|
if (Helenus.entity(iface).isDraftable()) {
|
||||||
if (Drafted.class.isAssignableFrom(iface)) {
|
result = Optional.of(cachedResult);
|
||||||
result = Optional.of(cachedResult);
|
} else {
|
||||||
} else {
|
result =
|
||||||
result = Optional.of(MappingUtil.clone(cachedResult));
|
Optional.of(
|
||||||
}
|
(E)
|
||||||
sessionCacheHits.mark();
|
SerializationUtils.<Serializable>clone(
|
||||||
cacheHits.mark();
|
(Serializable) cachedResult));
|
||||||
uow.recordCacheAndDatabaseOperationCount(1, 0);
|
}
|
||||||
} catch (CloneNotSupportedException e) {
|
sessionCacheHits.mark();
|
||||||
result = Optional.empty();
|
cacheHits.mark();
|
||||||
sessionCacheMiss.mark();
|
uow.recordCacheAndDatabaseOperationCount(1, 0);
|
||||||
cacheMiss.mark();
|
if (result.isPresent()) {
|
||||||
uow.recordCacheAndDatabaseOperationCount(-1, 0);
|
updateCache = true;
|
||||||
} finally {
|
} else {
|
||||||
if (result.isPresent()) {
|
updateCache = false;
|
||||||
updateCache = true;
|
|
||||||
} else {
|
|
||||||
updateCache = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
updateCache = false;
|
updateCache = false;
|
||||||
|
|
|
@ -24,6 +24,7 @@ import com.google.common.base.Function;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
@ -31,12 +32,13 @@ import java.util.concurrent.CompletionException;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import net.helenus.core.AbstractSessionOperations;
|
import net.helenus.core.AbstractSessionOperations;
|
||||||
|
import net.helenus.core.Helenus;
|
||||||
import net.helenus.core.UnitOfWork;
|
import net.helenus.core.UnitOfWork;
|
||||||
import net.helenus.core.cache.CacheUtil;
|
import net.helenus.core.cache.CacheUtil;
|
||||||
import net.helenus.core.cache.Facet;
|
import net.helenus.core.cache.Facet;
|
||||||
import net.helenus.core.reflect.Drafted;
|
|
||||||
import net.helenus.mapping.MappingUtil;
|
import net.helenus.mapping.MappingUtil;
|
||||||
import net.helenus.support.Fun;
|
import net.helenus.support.Fun;
|
||||||
|
import org.apache.commons.lang3.SerializationUtils;
|
||||||
|
|
||||||
public abstract class AbstractStreamOperation<E, O extends AbstractStreamOperation<E, O>>
|
public abstract class AbstractStreamOperation<E, O extends AbstractStreamOperation<E, O>>
|
||||||
extends AbstractStatementOperation<E, O> {
|
extends AbstractStatementOperation<E, O> {
|
||||||
|
@ -160,26 +162,20 @@ public abstract class AbstractStreamOperation<E, O extends AbstractStreamOperati
|
||||||
if (cachedResult != null) {
|
if (cachedResult != null) {
|
||||||
Class<?> iface = MappingUtil.getMappingInterface(cachedResult);
|
Class<?> iface = MappingUtil.getMappingInterface(cachedResult);
|
||||||
E result = null;
|
E result = null;
|
||||||
try {
|
if (Helenus.entity(iface).isDraftable()) {
|
||||||
if (Drafted.class.isAssignableFrom(iface)) {
|
result = cachedResult;
|
||||||
result = cachedResult;
|
} else {
|
||||||
} else {
|
result =
|
||||||
result = MappingUtil.clone(cachedResult);
|
(E) SerializationUtils.<Serializable>clone((Serializable) cachedResult);
|
||||||
}
|
}
|
||||||
resultStream = Stream.of(result);
|
resultStream = Stream.of(result);
|
||||||
sessionCacheHits.mark();
|
sessionCacheHits.mark();
|
||||||
cacheHits.mark();
|
cacheHits.mark();
|
||||||
uow.recordCacheAndDatabaseOperationCount(1, 0);
|
uow.recordCacheAndDatabaseOperationCount(1, 0);
|
||||||
} catch (CloneNotSupportedException e) {
|
if (result != null) {
|
||||||
resultStream = null;
|
updateCache = true;
|
||||||
sessionCacheMiss.mark();
|
} else {
|
||||||
uow.recordCacheAndDatabaseOperationCount(-1, 0);
|
updateCache = false;
|
||||||
} finally {
|
|
||||||
if (result != null) {
|
|
||||||
updateCache = true;
|
|
||||||
} else {
|
|
||||||
updateCache = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
updateCache = false;
|
updateCache = false;
|
||||||
|
|
|
@ -31,7 +31,6 @@ import net.helenus.core.cache.CacheUtil;
|
||||||
import net.helenus.core.cache.Facet;
|
import net.helenus.core.cache.Facet;
|
||||||
import net.helenus.core.cache.UnboundFacet;
|
import net.helenus.core.cache.UnboundFacet;
|
||||||
import net.helenus.core.reflect.DefaultPrimitiveTypes;
|
import net.helenus.core.reflect.DefaultPrimitiveTypes;
|
||||||
import net.helenus.core.reflect.Drafted;
|
|
||||||
import net.helenus.core.reflect.HelenusPropertyNode;
|
import net.helenus.core.reflect.HelenusPropertyNode;
|
||||||
import net.helenus.core.reflect.MapExportable;
|
import net.helenus.core.reflect.MapExportable;
|
||||||
import net.helenus.mapping.HelenusEntity;
|
import net.helenus.mapping.HelenusEntity;
|
||||||
|
@ -211,7 +210,7 @@ public final class InsertOperation<T> extends AbstractOperation<T, InsertOperati
|
||||||
|
|
||||||
private T newInstance(Class<?> iface) {
|
private T newInstance(Class<?> iface) {
|
||||||
if (values.size() > 0) {
|
if (values.size() > 0) {
|
||||||
boolean immutable = iface.isAssignableFrom(Drafted.class);
|
boolean immutable = entity.isDraftable();
|
||||||
Collection<HelenusProperty> properties = entity.getOrderedProperties();
|
Collection<HelenusProperty> properties = entity.getOrderedProperties();
|
||||||
Map<String, Object> backingMap = new HashMap<String, Object>(properties.size());
|
Map<String, Object> backingMap = new HashMap<String, Object>(properties.size());
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,9 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else if (draft != null) {
|
} else if (draft != null) {
|
||||||
String key = prop.getPropertyName();
|
String key = prop.getPropertyName();
|
||||||
list = (List<V>) draftMap.get(key);
|
list =
|
||||||
|
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||||
|
draft.put(key, list);
|
||||||
list.add(0, value);
|
list.add(0, value);
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else {
|
} else {
|
||||||
|
@ -235,7 +237,9 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else if (draft != null && value.size() > 0) {
|
} else if (draft != null && value.size() > 0) {
|
||||||
String key = p.getProperty().getPropertyName();
|
String key = p.getProperty().getPropertyName();
|
||||||
list = (List<V>) draftMap.get(key);
|
list =
|
||||||
|
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||||
|
draft.put(key, list);
|
||||||
list.addAll(0, value);
|
list.addAll(0, value);
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else {
|
} else {
|
||||||
|
@ -266,7 +270,10 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
||||||
list = (List<V>) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false);
|
list = (List<V>) BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false);
|
||||||
} else {
|
} else {
|
||||||
String key = prop.getPropertyName();
|
String key = prop.getPropertyName();
|
||||||
list = (List<V>) draftMap.get(key);
|
list =
|
||||||
|
(List<V>)
|
||||||
|
new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||||
|
draft.put(key, list);
|
||||||
}
|
}
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
list.add(0, value);
|
list.add(0, value);
|
||||||
|
@ -305,7 +312,9 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else if (draft != null) {
|
} else if (draft != null) {
|
||||||
String key = prop.getPropertyName();
|
String key = prop.getPropertyName();
|
||||||
list = (List<V>) draftMap.get(key);
|
list =
|
||||||
|
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||||
|
draft.put(key, list);
|
||||||
list.add(value);
|
list.add(value);
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else {
|
} else {
|
||||||
|
@ -336,7 +345,9 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else if (draft != null && value.size() > 0) {
|
} else if (draft != null && value.size() > 0) {
|
||||||
String key = prop.getPropertyName();
|
String key = prop.getPropertyName();
|
||||||
list = (List<V>) draftMap.get(key);
|
list =
|
||||||
|
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||||
|
draft.put(key, list);
|
||||||
list.addAll(value);
|
list.addAll(value);
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else {
|
} else {
|
||||||
|
@ -367,7 +378,9 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else if (draft != null) {
|
} else if (draft != null) {
|
||||||
String key = prop.getPropertyName();
|
String key = prop.getPropertyName();
|
||||||
list = (List<V>) draftMap.get(key);
|
list =
|
||||||
|
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||||
|
draft.put(key, list);
|
||||||
list.remove(value);
|
list.remove(value);
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else {
|
} else {
|
||||||
|
@ -398,7 +411,9 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else if (draft != null) {
|
} else if (draft != null) {
|
||||||
String key = prop.getPropertyName();
|
String key = prop.getPropertyName();
|
||||||
list = (List<V>) draftMap.get(key);
|
list =
|
||||||
|
(List<V>) new ArrayList<V>((List<V>) draftMap.get(key)); // copy immutable -> mutable list
|
||||||
|
draft.put(key, list);
|
||||||
list.removeAll(value);
|
list.removeAll(value);
|
||||||
facet = new BoundFacet(prop, list);
|
facet = new BoundFacet(prop, list);
|
||||||
} else {
|
} else {
|
||||||
|
@ -467,7 +482,8 @@ public final class UpdateOperation<E> extends AbstractFilterOperation<E, UpdateO
|
||||||
facet = new BoundFacet(prop, set);
|
facet = new BoundFacet(prop, set);
|
||||||
} else if (draft != null) {
|
} else if (draft != null) {
|
||||||
String key = prop.getPropertyName();
|
String key = prop.getPropertyName();
|
||||||
set = (Set<V>) draftMap.get(key);
|
set = (Set<V>) new HashSet<V>((Set<V>) draftMap.get(key));
|
||||||
|
draft.put(key, set);
|
||||||
set.add(value);
|
set.add(value);
|
||||||
facet = new BoundFacet(prop, set);
|
facet = new BoundFacet(prop, set);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -34,4 +34,6 @@ public interface HelenusEntity {
|
||||||
HelenusProperty getProperty(String name);
|
HelenusProperty getProperty(String name);
|
||||||
|
|
||||||
List<Facet> getFacets();
|
List<Facet> getFacets();
|
||||||
|
|
||||||
|
boolean isDraftable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ public final class HelenusMappingEntity implements HelenusEntity {
|
||||||
private final HelenusEntityType type;
|
private final HelenusEntityType type;
|
||||||
private final IdentityName name;
|
private final IdentityName name;
|
||||||
private final boolean cacheable;
|
private final boolean cacheable;
|
||||||
|
private final boolean draftable;
|
||||||
private final ImmutableMap<String, Method> methods;
|
private final ImmutableMap<String, Method> methods;
|
||||||
private final ImmutableMap<String, HelenusProperty> props;
|
private final ImmutableMap<String, HelenusProperty> props;
|
||||||
private final ImmutableList<HelenusProperty> orderedProps;
|
private final ImmutableList<HelenusProperty> orderedProps;
|
||||||
|
@ -112,6 +113,16 @@ public final class HelenusMappingEntity implements HelenusEntity {
|
||||||
// Caching
|
// Caching
|
||||||
cacheable = (null != iface.getDeclaredAnnotation(Cacheable.class));
|
cacheable = (null != iface.getDeclaredAnnotation(Cacheable.class));
|
||||||
|
|
||||||
|
// Draft
|
||||||
|
Class<?> draft;
|
||||||
|
try {
|
||||||
|
draft = Class.forName(iface.getName() + "$Draft");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
draft = null;
|
||||||
|
}
|
||||||
|
draftable = (draft != null);
|
||||||
|
|
||||||
|
// Materialized view
|
||||||
List<HelenusProperty> primaryKeyProperties = new ArrayList<>();
|
List<HelenusProperty> primaryKeyProperties = new ArrayList<>();
|
||||||
ImmutableList.Builder<Facet> facetsBuilder = ImmutableList.builder();
|
ImmutableList.Builder<Facet> facetsBuilder = ImmutableList.builder();
|
||||||
if (iface.getDeclaredAnnotation(MaterializedView.class) == null) {
|
if (iface.getDeclaredAnnotation(MaterializedView.class) == null) {
|
||||||
|
@ -212,6 +223,11 @@ public final class HelenusMappingEntity implements HelenusEntity {
|
||||||
return cacheable;
|
return cacheable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDraftable() {
|
||||||
|
return draftable;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getMappingInterface() {
|
public Class<?> getMappingInterface() {
|
||||||
return iface;
|
return iface;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
package net.helenus.mapping;
|
package net.helenus.mapping;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -305,28 +304,6 @@ public final class MappingUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/a/4882306/366692
|
|
||||||
public static <T> T clone(T object) throws CloneNotSupportedException {
|
|
||||||
Object clone = null;
|
|
||||||
|
|
||||||
// Use reflection, because there is no other way
|
|
||||||
try {
|
|
||||||
Method method = object.getClass().getMethod("clone");
|
|
||||||
clone = method.invoke(object);
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
rethrow(e.getCause());
|
|
||||||
} catch (Exception cause) {
|
|
||||||
rethrow(cause);
|
|
||||||
}
|
|
||||||
if (object.getClass().isInstance(clone)) {
|
|
||||||
@SuppressWarnings("unchecked") // clone class <= object class <= T
|
|
||||||
T t = (T) clone;
|
|
||||||
return t;
|
|
||||||
} else {
|
|
||||||
throw new ClassCastException(clone.getClass().getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void rethrow(Throwable cause) throws CloneNotSupportedException {
|
private static void rethrow(Throwable cause) throws CloneNotSupportedException {
|
||||||
if (cause instanceof RuntimeException) {
|
if (cause instanceof RuntimeException) {
|
||||||
throw (RuntimeException) cause;
|
throw (RuntimeException) cause;
|
||||||
|
|
|
@ -19,7 +19,6 @@ import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import net.helenus.core.reflect.Drafted;
|
|
||||||
import net.helenus.mapping.HelenusEntity;
|
import net.helenus.mapping.HelenusEntity;
|
||||||
import net.helenus.mapping.HelenusProperty;
|
import net.helenus.mapping.HelenusProperty;
|
||||||
import net.helenus.support.HelenusMappingException;
|
import net.helenus.support.HelenusMappingException;
|
||||||
|
@ -35,7 +34,7 @@ public final class ValueProviderMap implements Map<String, Object> {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.valueProvider = valueProvider;
|
this.valueProvider = valueProvider;
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.immutable = entity.getMappingInterface().isAssignableFrom(Drafted.class);
|
this.immutable = entity.isDraftable();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void throwShouldNeverCall(String methodName) {
|
private static void throwShouldNeverCall(String methodName) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import net.helenus.core.reflect.MapExportable;
|
||||||
import net.helenus.mapping.annotation.*;
|
import net.helenus.mapping.annotation.*;
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
public interface Inventory extends Entity, Drafted<Inventory> {
|
public interface Inventory extends Entity {
|
||||||
|
|
||||||
static Inventory inventory = Helenus.dsl(Inventory.class);
|
static Inventory inventory = Helenus.dsl(Inventory.class);
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ public interface Inventory extends Entity, Drafted<Inventory> {
|
||||||
return new Draft(this);
|
return new Draft(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Draft extends AbstractAuditedEntityDraft<Inventory> {
|
class Draft extends AbstractAuditedEntityDraft<Inventory> implements Drafted<Inventory> {
|
||||||
|
|
||||||
// Entity/Draft pattern-enabling methods:
|
// Entity/Draft pattern-enabling methods:
|
||||||
Draft(UUID id) {
|
Draft(UUID id) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import net.helenus.mapping.annotation.*;
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
@Cacheable
|
@Cacheable
|
||||||
public interface Supply extends Entity, Drafted<Supply> {
|
public interface Supply extends Entity {
|
||||||
|
|
||||||
static Supply supply = Helenus.dsl(Supply.class);
|
static Supply supply = Helenus.dsl(Supply.class);
|
||||||
|
|
||||||
|
@ -52,8 +52,7 @@ public interface Supply extends Entity, Drafted<Supply> {
|
||||||
return new Draft(this);
|
return new Draft(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Draft extends AbstractEntityDraft<Supply> {
|
class Draft extends AbstractEntityDraft<Supply> implements Drafted<Supply> {
|
||||||
|
|
||||||
// Entity/Draft pattern-enabling methods:
|
// Entity/Draft pattern-enabling methods:
|
||||||
Draft(String region) {
|
Draft(String region) {
|
||||||
super(null);
|
super(null);
|
||||||
|
|
|
@ -19,6 +19,7 @@ import static net.helenus.core.Query.eq;
|
||||||
|
|
||||||
import com.datastax.driver.core.ConsistencyLevel;
|
import com.datastax.driver.core.ConsistencyLevel;
|
||||||
import com.datastax.driver.core.utils.UUIDs;
|
import com.datastax.driver.core.utils.UUIDs;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import net.bytebuddy.utility.RandomString;
|
import net.bytebuddy.utility.RandomString;
|
||||||
|
@ -38,7 +39,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
@Cacheable
|
@Cacheable
|
||||||
interface Widget extends Entity {
|
interface Widget extends Entity, Serializable {
|
||||||
@PartitionKey
|
@PartitionKey
|
||||||
UUID id();
|
UUID id();
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ public interface Account {
|
||||||
return new Draft();
|
return new Draft();
|
||||||
}
|
}
|
||||||
|
|
||||||
class Draft implements Drafted { // TODO
|
class Draft implements Drafted<Account> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> mutated() {
|
public Set<String> mutated() {
|
||||||
|
@ -47,7 +47,7 @@ public interface Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object build() {
|
public Account build() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue