From a126607c092e1e71d27d4bb28fb60054f5c06519 Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Wed, 9 Aug 2017 16:20:38 -0400 Subject: [PATCH] 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). --- pom.xml | 2 +- .../core/operation/InsertOperation.java | 182 +++++++++--------- .../helenus/core/reflect/MapExportable.java | 3 + 3 files changed, 95 insertions(+), 92 deletions(-) diff --git a/pom.xml b/pom.xml index 3cb9e95..e6708fd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 net.helenus helenus-core - 2.0.13-SNAPSHOT + 2.0.14-SNAPSHOT jar helenus diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index 403c4b2..c57b776 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -15,21 +15,14 @@ */ package net.helenus.core.operation; -import java.util.*; - import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.querybuilder.BuiltStatement; import com.datastax.driver.core.querybuilder.Insert; 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.Getter; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.core.reflect.MapExportable; -import net.helenus.mapping.ColumnType; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; import net.helenus.mapping.MappingUtil; @@ -37,36 +30,43 @@ import net.helenus.mapping.value.BeanColumnValueProvider; import net.helenus.support.Fun; import net.helenus.support.HelenusMappingException; +import java.util.*; + public final class InsertOperation extends AbstractOperation { - private HelenusEntity entity; + private HelenusEntity entity; - private final List> values = new ArrayList>(); - private boolean ifNotExists; + private final List> values = new ArrayList>(); + private boolean ifNotExists; - private int[] ttl; - private long[] timestamp; + private int[] ttl; + private long[] timestamp; - public InsertOperation(AbstractSessionOperations sessionOperations, boolean ifNotExists) { - super(sessionOperations); + public InsertOperation(AbstractSessionOperations sessionOperations, boolean ifNotExists) { + super(sessionOperations); - this.ifNotExists = ifNotExists; - } + this.ifNotExists = ifNotExists; + } - public InsertOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, Object pojo, - boolean ifNotExists) { - super(sessionOperations); + public InsertOperation(AbstractSessionOperations sessionOperations, HelenusEntity entity, Object pojo, + boolean ifNotExists) { + super(sessionOperations); - this.entity = entity; - this.ifNotExists = ifNotExists; - Set keys = (pojo instanceof MapExportable) ? ((MapExportable)pojo).toMap().keySet() : null; + this.entity = entity; + this.ifNotExists = ifNotExists; Collection properties = entity.getOrderedProperties(); + Set keys = null; + + if (pojo instanceof MapExportable) { + keys = ((MapExportable) pojo).mutated(); + if (keys == null) { + keys = ((MapExportable) pojo).toMap().keySet(); + } + } for (HelenusProperty prop : properties) { - // Skip properties that are not in the map of the pojo we're storing. This creates a path - // for entity instances to be {in,up}serted without including all columns in the INSERT statement. - if (keys == null || keys.contains(prop.getPropertyName())) { + if (keys == null || keys.contains(prop.getPropertyName())) { Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop); value = sessionOps.getValuePreparer().prepareColumnValue(value, prop); @@ -78,91 +78,91 @@ public final class InsertOperation extends AbstractOperation InsertOperation value(Getter getter, V val) { + public InsertOperation value(Getter getter, V val) { - Objects.requireNonNull(getter, "getter is empty"); + Objects.requireNonNull(getter, "getter is empty"); - if (val != null) { - HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); - Object value = sessionOps.getValuePreparer().prepareColumnValue(val, node.getProperty()); + if (val != null) { + HelenusPropertyNode node = MappingUtil.resolveMappingProperty(getter); + Object value = sessionOps.getValuePreparer().prepareColumnValue(val, node.getProperty()); - if (value != null) { - values.add(Fun.Tuple2.of(node, value)); - } - } + if (value != null) { + values.add(Fun.Tuple2.of(node, value)); + } + } - return this; - } + return this; + } - @Override - public BuiltStatement buildStatement() { + @Override + public BuiltStatement buildStatement() { - values.forEach(t -> addPropertyNode(t._1)); + values.forEach(t -> addPropertyNode(t._1)); - if (values.isEmpty()) - return null; + if (values.isEmpty()) + return null; - if (entity == null) { - throw new HelenusMappingException("unknown entity"); - } + if (entity == null) { + throw new HelenusMappingException("unknown entity"); + } - Insert insert = QueryBuilder.insertInto(entity.getName().toCql()); + Insert insert = QueryBuilder.insertInto(entity.getName().toCql()); - if (ifNotExists) { - insert.ifNotExists(); - } + if (ifNotExists) { + insert.ifNotExists(); + } - values.forEach(t -> { - insert.value(t._1.getColumnName(), t._2); - }); + values.forEach(t -> { + insert.value(t._1.getColumnName(), t._2); + }); - if (this.ttl != null) { - insert.using(QueryBuilder.ttl(this.ttl[0])); - } - if (this.timestamp != null) { - insert.using(QueryBuilder.timestamp(this.timestamp[0])); - } + if (this.ttl != null) { + insert.using(QueryBuilder.ttl(this.ttl[0])); + } + if (this.timestamp != null) { + insert.using(QueryBuilder.timestamp(this.timestamp[0])); + } - return insert; - } + return insert; + } - @Override - public ResultSet transform(ResultSet resultSet) { - return resultSet; - } + @Override + public ResultSet transform(ResultSet resultSet) { + return resultSet; + } - public InsertOperation usingTtl(int ttl) { - this.ttl = new int[1]; - this.ttl[0] = ttl; - return this; - } + public InsertOperation usingTtl(int ttl) { + this.ttl = new int[1]; + this.ttl[0] = ttl; + return this; + } - public InsertOperation usingTimestamp(long timestamp) { - this.timestamp = new long[1]; - this.timestamp[0] = timestamp; - return this; - } + public InsertOperation usingTimestamp(long timestamp) { + this.timestamp = new long[1]; + this.timestamp[0] = timestamp; + return this; + } - private void addPropertyNode(HelenusPropertyNode p) { - if (entity == null) { - entity = p.getEntity(); - } else if (entity != p.getEntity()) { - throw new HelenusMappingException("you can insert only single entity " + entity.getMappingInterface() - + " or " + p.getEntity().getMappingInterface()); - } - } + private void addPropertyNode(HelenusPropertyNode p) { + if (entity == null) { + entity = p.getEntity(); + } else if (entity != p.getEntity()) { + throw new HelenusMappingException("you can insert only single entity " + entity.getMappingInterface() + + " or " + p.getEntity().getMappingInterface()); + } + } } diff --git a/src/main/java/net/helenus/core/reflect/MapExportable.java b/src/main/java/net/helenus/core/reflect/MapExportable.java index 1e91946..fcb0e19 100644 --- a/src/main/java/net/helenus/core/reflect/MapExportable.java +++ b/src/main/java/net/helenus/core/reflect/MapExportable.java @@ -16,6 +16,7 @@ package net.helenus.core.reflect; import java.util.Map; +import java.util.Set; public interface MapExportable { @@ -23,4 +24,6 @@ public interface MapExportable { Map toMap(); + default Set mutated() { return null; } + }