Added check for mutated set so that the backingMap could contain all object values. The other option was to auto-refresh the instance's backing map when a getter is invoked for a valid property that isn't included in the backing map (which still may be handy/required for caching to work).

This commit is contained in:
Greg Burd 2017-08-09 16:20:38 -04:00
parent 871c8d0c90
commit a126607c09
3 changed files with 95 additions and 92 deletions

View file

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>net.helenus</groupId> <groupId>net.helenus</groupId>
<artifactId>helenus-core</artifactId> <artifactId>helenus-core</artifactId>
<version>2.0.13-SNAPSHOT</version> <version>2.0.14-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>helenus</name> <name>helenus</name>

View file

@ -15,21 +15,14 @@
*/ */
package net.helenus.core.operation; package net.helenus.core.operation;
import java.util.*;
import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.BuiltStatement;
import com.datastax.driver.core.querybuilder.Insert; import com.datastax.driver.core.querybuilder.Insert;
import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.helenus.core.AbstractSessionOperations; import net.helenus.core.AbstractSessionOperations;
import net.helenus.core.Getter; import net.helenus.core.Getter;
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.ColumnType;
import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusEntity;
import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.HelenusProperty;
import net.helenus.mapping.MappingUtil; import net.helenus.mapping.MappingUtil;
@ -37,36 +30,43 @@ import net.helenus.mapping.value.BeanColumnValueProvider;
import net.helenus.support.Fun; import net.helenus.support.Fun;
import net.helenus.support.HelenusMappingException; import net.helenus.support.HelenusMappingException;
import java.util.*;
public final class InsertOperation extends AbstractOperation<ResultSet, InsertOperation> { public final class InsertOperation extends AbstractOperation<ResultSet, InsertOperation> {
private HelenusEntity entity; private HelenusEntity entity;
private final List<Fun.Tuple2<HelenusPropertyNode, Object>> values = new ArrayList<Fun.Tuple2<HelenusPropertyNode, Object>>(); private final List<Fun.Tuple2<HelenusPropertyNode, Object>> values = new ArrayList<Fun.Tuple2<HelenusPropertyNode, Object>>();
private boolean ifNotExists; private boolean ifNotExists;
private int[] ttl; private int[] ttl;
private long[] timestamp; private long[] timestamp;
public InsertOperation(AbstractSessionOperations sessionOperations, boolean ifNotExists) { public InsertOperation(AbstractSessionOperations sessionOperations, boolean ifNotExists) {
super(sessionOperations); super(sessionOperations);
this.ifNotExists = ifNotExists; this.ifNotExists = ifNotExists;
} }
public InsertOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, Object pojo, public InsertOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, Object pojo,
boolean ifNotExists) { boolean ifNotExists) {
super(sessionOperations); super(sessionOperations);
this.entity = entity; this.entity = entity;
this.ifNotExists = ifNotExists; this.ifNotExists = ifNotExists;
Set<String> keys = (pojo instanceof MapExportable) ? ((MapExportable)pojo).toMap().keySet() : null;
Collection<HelenusProperty> properties = entity.getOrderedProperties(); Collection<HelenusProperty> properties = entity.getOrderedProperties();
Set<String> keys = null;
if (pojo instanceof MapExportable) {
keys = ((MapExportable) pojo).mutated();
if (keys == null) {
keys = ((MapExportable) pojo).toMap().keySet();
}
}
for (HelenusProperty prop : properties) { for (HelenusProperty prop : properties) {
// Skip properties that are not in the map of the pojo we're storing. This creates a path if (keys == null || keys.contains(prop.getPropertyName())) {
// for entity instances to be {in,up}serted without including all columns in the INSERT statement.
if (keys == null || keys.contains(prop.getPropertyName())) {
Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop);
value = sessionOps.getValuePreparer().prepareColumnValue(value, prop); value = sessionOps.getValuePreparer().prepareColumnValue(value, prop);
@ -78,91 +78,91 @@ public final class InsertOperation extends AbstractOperation<ResultSet, InsertOp
} }
} }
} }
public InsertOperation ifNotExists() { public InsertOperation ifNotExists() {
this.ifNotExists = true; this.ifNotExists = true;
return this; return this;
} }
public InsertOperation ifNotExists(boolean enable) { public InsertOperation ifNotExists(boolean enable) {
this.ifNotExists = enable; this.ifNotExists = enable;
return this; return this;
} }
public <V> InsertOperation value(Getter<V> getter, V val) { public <V> InsertOperation value(Getter<V> getter, V val) {
Objects.requireNonNull(getter, "getter is empty"); Objects.requireNonNull(getter, "getter is empty");
if (val != null) { if (val != null) {
HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter);
Object value = sessionOps.getValuePreparer().prepareColumnValue(val, node.getProperty()); Object value = sessionOps.getValuePreparer().prepareColumnValue(val, node.getProperty());
if (value != null) { if (value != null) {
values.add(Fun.Tuple2.of(node, value)); values.add(Fun.Tuple2.of(node, value));
} }
} }
return this; return this;
} }
@Override @Override
public BuiltStatement buildStatement() { public BuiltStatement buildStatement() {
values.forEach(t -> addPropertyNode(t._1)); values.forEach(t -> addPropertyNode(t._1));
if (values.isEmpty()) if (values.isEmpty())
return null; return null;
if (entity == null) { if (entity == null) {
throw new HelenusMappingException("unknown entity"); throw new HelenusMappingException("unknown entity");
} }
Insert insert = QueryBuilder.insertInto(entity.getName().toCql()); Insert insert = QueryBuilder.insertInto(entity.getName().toCql());
if (ifNotExists) { if (ifNotExists) {
insert.ifNotExists(); insert.ifNotExists();
} }
values.forEach(t -> { values.forEach(t -> {
insert.value(t._1.getColumnName(), t._2); insert.value(t._1.getColumnName(), t._2);
}); });
if (this.ttl != null) { if (this.ttl != null) {
insert.using(QueryBuilder.ttl(this.ttl[0])); insert.using(QueryBuilder.ttl(this.ttl[0]));
} }
if (this.timestamp != null) { if (this.timestamp != null) {
insert.using(QueryBuilder.timestamp(this.timestamp[0])); insert.using(QueryBuilder.timestamp(this.timestamp[0]));
} }
return insert; return insert;
} }
@Override @Override
public ResultSet transform(ResultSet resultSet) { public ResultSet transform(ResultSet resultSet) {
return resultSet; return resultSet;
} }
public InsertOperation usingTtl(int ttl) { public InsertOperation usingTtl(int ttl) {
this.ttl = new int[1]; this.ttl = new int[1];
this.ttl[0] = ttl; this.ttl[0] = ttl;
return this; return this;
} }
public InsertOperation usingTimestamp(long timestamp) { public InsertOperation usingTimestamp(long timestamp) {
this.timestamp = new long[1]; this.timestamp = new long[1];
this.timestamp[0] = timestamp; this.timestamp[0] = timestamp;
return this; return this;
} }
private void addPropertyNode(HelenusPropertyNode p) { private void addPropertyNode(HelenusPropertyNode p) {
if (entity == null) { if (entity == null) {
entity = p.getEntity(); entity = p.getEntity();
} else if (entity != p.getEntity()) { } else if (entity != p.getEntity()) {
throw new HelenusMappingException("you can insert only single entity " + entity.getMappingInterface() throw new HelenusMappingException("you can insert only single entity " + entity.getMappingInterface()
+ " or " + p.getEntity().getMappingInterface()); + " or " + p.getEntity().getMappingInterface());
} }
} }
} }

View file

@ -16,6 +16,7 @@
package net.helenus.core.reflect; package net.helenus.core.reflect;
import java.util.Map; import java.util.Map;
import java.util.Set;
public interface MapExportable { public interface MapExportable {
@ -23,4 +24,6 @@ public interface MapExportable {
Map<String, Object> toMap(); Map<String, Object> toMap();
default Set<String> mutated() { return null; }
} }