diff --git a/README.md b/README.md
index 8ac7a8115..4310d285d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Weaviate Java client
+# Weaviate Java client
[](https://github.com/weaviate/java-client/actions/workflows/.github/workflows/test.yaml)
@@ -183,7 +183,7 @@ WeaviateClient wcd = WeaviateClient.connectToWeaviateCloud("my-cluster-url.io",
> [!TIP]
> The client holds a number of resources (HTTP connection pools, gRPC channel) which must be disposed of correclty then they are no longer needed.
> If the client's lifecycle is tied to that of your app, closing the client via `client.close()` is a good way to do that.
->
+>
> Otherwise, use the client inside a [try-with-resources](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) statement:
>
>```java
@@ -684,7 +684,7 @@ var song1 = songs.query.byId(
song -> song.returnReferences(QueryReference.single("artist"))
);
System.out.println(
- "Artist's last name is: " +
+ "Artist's last name is: " +
song1.properties().artist().lastName()
);
```
diff --git a/assets/duke-client6.png b/logo.png
similarity index 100%
rename from assets/duke-client6.png
rename to logo.png
diff --git a/src/it/java/io/weaviate/integration/ORMITest.java b/src/it/java/io/weaviate/integration/ORMITest.java
index d46d1600c..16b5b3717 100644
--- a/src/it/java/io/weaviate/integration/ORMITest.java
+++ b/src/it/java/io/weaviate/integration/ORMITest.java
@@ -1,5 +1,6 @@
package io.weaviate.integration;
+import java.io.IOException;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Map;
@@ -14,6 +15,7 @@
import io.weaviate.ConcurrentTest;
import io.weaviate.client6.v1.api.WeaviateClient;
import io.weaviate.client6.v1.api.collections.CollectionConfig;
+import io.weaviate.client6.v1.api.collections.WeaviateObject;
import io.weaviate.client6.v1.api.collections.annotations.Collection;
import io.weaviate.client6.v1.api.collections.annotations.Property;
import io.weaviate.client6.v1.api.collections.data.InsertManyResponse.InsertObject;
@@ -23,7 +25,7 @@
public class ORMITest extends ConcurrentTest {
private static WeaviateClient client = Container.WEAVIATE.getClient();
- @Collection("ORMITest")
+ @Collection("ORMITestThings")
static record Thing(
// text / text[]
String text,
@@ -95,7 +97,7 @@ public void test_createCollection() throws Exception {
// Assert
Assertions.assertThat(config).get()
- .returns("ORMITest", CollectionConfig::collectionName)
+ .returns("ORMITestThings", CollectionConfig::collectionName)
.extracting(CollectionConfig::properties,
InstanceOfAssertFactories.list(io.weaviate.client6.v1.api.collections.Property.class))
.extracting(p -> Map.entry(
@@ -307,4 +309,45 @@ public void test_insertManyAndQuery() throws Exception {
.usingRecursiveComparison(COMPARISON_CONFIG)
.asInstanceOf(InstanceOfAssertFactories.list(Thing.class));
}
+
+ @Collection("ORMITestSongs")
+ record Song(
+ String title,
+ String album,
+ int year,
+ boolean hasAward,
+ Long monthlyListeners) {
+ }
+
+ /**
+ * Test that serialization works correctly when some fields are null and
+ * deserialization works correctly when some properties are not returned.
+ */
+ @Test
+ public void test_partialScan() throws IOException {
+ client.collections.create(Song.class);
+
+ var songs = client.collections.use(Song.class);
+
+ // Act: insert with nulls
+ var dystopia = songs.data.insert(new Song(
+ "Dystopia",
+ null,
+ 2016,
+ true,
+ null));
+
+ // Act: return subset of the properties
+ var got = songs.query.byId(dystopia.uuid(),
+ q -> q.returnProperties("title", "hasAward"));
+
+ // Assert
+ Assertions.assertThat(got).get()
+ .extracting(WeaviateObject::properties)
+ .returns("Dystopia", Song::title)
+ .returns(null, Song::album)
+ .returns(0, Song::year)
+ .returns(true, Song::hasAward)
+ .returns(null, Song::monthlyListeners);
+ }
}
diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java
index 4cd096386..fa07d67d5 100644
--- a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java
+++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java
@@ -221,7 +221,7 @@ private static void setProperty(String property, WeaviateProtoProperties.Val
} else if (value.hasBoolValue()) {
builder.setBoolean(property, value.getBoolValue());
} else if (value.hasIntValue()) {
- builder.setInteger(property, value.getIntValue());
+ builder.setLong(property, value.getIntValue());
} else if (value.hasNumberValue()) {
builder.setDouble(property, value.getNumberValue());
} else if (value.hasBlobValue()) {
diff --git a/src/main/java/io/weaviate/client6/v1/internal/orm/MapBuilder.java b/src/main/java/io/weaviate/client6/v1/internal/orm/MapBuilder.java
index 0e2c94c99..6d1383160 100644
--- a/src/main/java/io/weaviate/client6/v1/internal/orm/MapBuilder.java
+++ b/src/main/java/io/weaviate/client6/v1/internal/orm/MapBuilder.java
@@ -25,7 +25,7 @@ public void setBoolean(String property, Boolean value) {
}
@Override
- public void setInteger(String property, Long value) {
+ public void setLong(String property, Long value) {
properties.put(property, value);
}
diff --git a/src/main/java/io/weaviate/client6/v1/internal/orm/PojoBuilder.java b/src/main/java/io/weaviate/client6/v1/internal/orm/PojoBuilder.java
index 1fa65750c..223fd0f53 100644
--- a/src/main/java/io/weaviate/client6/v1/internal/orm/PojoBuilder.java
+++ b/src/main/java/io/weaviate/client6/v1/internal/orm/PojoBuilder.java
@@ -11,11 +11,34 @@
import org.apache.commons.lang3.ArrayUtils;
final class PojoBuilder implements PropertiesBuilder {
+ private static final Map, Object> PRIMITIVE_DEFAULTS;
+
+ static {
+ PRIMITIVE_DEFAULTS = Map.of(
+ boolean.class, false,
+ short.class, (short) 0,
+ int.class, 0,
+ long.class, 0L,
+ float.class, 0f,
+ double.class, 0d);
+ }
+
private final PojoDescriptor descriptor;
private final Constructor ctor;
private final Map ctorArgs;
static record Arg(Class> type, Object value) {
+ /**
+ * Create a new Arg, replacing a null value with
+ * default if the type is a known primitive class.
+ */
+ static Arg withPrimitiveDefault(Class> type, Object value) {
+ if (PRIMITIVE_DEFAULTS.containsKey(type)) {
+ return new Arg(type, PRIMITIVE_DEFAULTS.get(type));
+ }
+ return new Arg(type, value);
+ }
+
Arg withValue(Object value) {
return new Arg(this.type, value);
}
@@ -31,7 +54,7 @@ Arg withValue(Object value) {
.map(arg -> {
// LinkedHashMap allows null values.
var type = arg.getType();
- ctorArgs.put(arg.getName(), new Arg(type, null));
+ ctorArgs.put(arg.getName(), Arg.withPrimitiveDefault(type, null));
return type;
})
.toArray(Class>[]::new);
@@ -103,8 +126,7 @@ public void setBoolean(String propertyName, Boolean value) {
}
@Override
- // TODO: rename to setLong
- public void setInteger(String propertyName, Long value) {
+ public void setLong(String propertyName, Long value) {
if (isType(propertyName, short.class, Short.class)) {
setValue(propertyName, value.shortValue());
} else if (isType(propertyName, int.class, Integer.class)) {
diff --git a/src/main/java/io/weaviate/client6/v1/internal/orm/PropertiesBuilder.java b/src/main/java/io/weaviate/client6/v1/internal/orm/PropertiesBuilder.java
index dd46f87c9..797831640 100644
--- a/src/main/java/io/weaviate/client6/v1/internal/orm/PropertiesBuilder.java
+++ b/src/main/java/io/weaviate/client6/v1/internal/orm/PropertiesBuilder.java
@@ -11,7 +11,7 @@ public interface PropertiesBuilder {
void setBoolean(String property, Boolean value);
- void setInteger(String property, Long value);
+ void setLong(String property, Long value);
void setDouble(String property, Double value);