Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,6 @@
*/
package net.lecousin.reactive.data.relational.enhance;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

import org.apache.commons.lang3.mutable.MutableObject;
import org.springframework.core.CollectionFactory;
import org.springframework.data.mapping.MappingException;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import net.lecousin.reactive.data.relational.LcReactiveDataRelationalClient;
import net.lecousin.reactive.data.relational.model.ModelAccessException;
import net.lecousin.reactive.data.relational.model.ModelUtils;
Expand All @@ -38,14 +22,28 @@
import net.lecousin.reactive.data.relational.model.metadata.PropertyStaticMetadata;
import net.lecousin.reactive.data.relational.query.SelectQuery;
import net.lecousin.reactive.data.relational.query.criteria.Criteria;
import org.apache.commons.lang3.mutable.MutableObject;
import org.springframework.core.CollectionFactory;
import org.springframework.data.mapping.MappingException;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import reactor.core.CorePublisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

/**
* Internal state of an entity, allowing to implement features such as lazy loading, updated attributes detection...
*
* @author Guillaume Le Cousin
* @author Sebastian Nawrocki
*
*/
public class EntityState {
Expand Down Expand Up @@ -154,9 +152,10 @@ private void updatePersistedValues(Object entity) {

private void savePersistedValue(Field field, Object value) {
if (value != null && ModelUtils.isCollection(field)) {
List<Object> list = new LinkedList<>();
list.addAll(ModelUtils.getAsCollection(value));
persistedValues.put(field.getName(), list);
Collection<Object> valueAsCollection = ModelUtils.getAsCollection(value);
Collection<Object> collection = CollectionFactory.createApproximateCollection(valueAsCollection, 10);
collection.addAll(valueAsCollection);
persistedValues.put(field.getName(), collection);
} else {
persistedValues.put(field.getName(), value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@
*/
package net.lecousin.reactive.data.relational.model;

import net.lecousin.reactive.data.relational.annotations.CompositeId;
import net.lecousin.reactive.data.relational.enhance.EntityState;
import net.lecousin.reactive.data.relational.model.metadata.EntityMetadata;
import net.lecousin.reactive.data.relational.model.metadata.EntityStaticMetadata;
import net.lecousin.reactive.data.relational.model.metadata.PropertyMetadata;
import net.lecousin.reactive.data.relational.model.metadata.PropertyStaticMetadata;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.core.CollectionFactory;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
Expand All @@ -25,21 +39,6 @@
import java.util.List;
import java.util.function.Function;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.core.CollectionFactory;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import net.lecousin.reactive.data.relational.annotations.CompositeId;
import net.lecousin.reactive.data.relational.enhance.EntityState;
import net.lecousin.reactive.data.relational.model.metadata.EntityMetadata;
import net.lecousin.reactive.data.relational.model.metadata.EntityStaticMetadata;
import net.lecousin.reactive.data.relational.model.metadata.PropertyMetadata;
import net.lecousin.reactive.data.relational.model.metadata.PropertyStaticMetadata;

/**
* Utility methods.
*
Expand Down Expand Up @@ -120,9 +119,7 @@ public static boolean isCollection(Field field) {
public static boolean isCollectionType(Class<?> type) {
if (type.isArray())
return !char[].class.equals(type);
if (Collection.class.isAssignableFrom(type))
return true;
return false;
return Collection.class.isAssignableFrom(type);
}

/** Return the given object as a collection.
Expand Down Expand Up @@ -164,11 +161,9 @@ public static Class<?> getCollectionType(Field field) {
* @return type of elements
*/
public static Class<?> getRequiredCollectionType(Field field) {
if (field.getType().isArray())
return field.getType().getComponentType();
Type genType = field.getGenericType();
if (genType instanceof ParameterizedType)
return (Class<?>) ((ParameterizedType)genType).getActualTypeArguments()[0];
Class<?> collectionType = getCollectionType(field);
if (collectionType != null)
return collectionType;
throw new MappingException("Field is not a collection: " + field.getDeclaringClass().getName() + "." + field.getName());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
package net.lecousin.reactive.data.relational.test;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;

import javax.annotation.PostConstruct;

import net.lecousin.reactive.data.relational.LcReactiveDataRelationalClient;
import net.lecousin.reactive.data.relational.model.metadata.EntityStaticMetadata;
import net.lecousin.reactive.data.relational.query.SelectQuery;
import net.lecousin.reactive.data.relational.repository.LcR2dbcEntityTemplate;
import net.lecousin.reactive.data.relational.schema.RelationalDatabaseSchema;
import net.lecousin.reactive.data.relational.test.arraycolumns.EntityWithArrays;
import net.lecousin.reactive.data.relational.test.arraycolumns.UpdateableCollectionProperties;
import net.lecousin.reactive.data.relational.test.simplemodel.DateTypesWithTimeZone;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -25,13 +21,17 @@
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;

import net.lecousin.reactive.data.relational.LcReactiveDataRelationalClient;
import net.lecousin.reactive.data.relational.model.metadata.EntityStaticMetadata;
import net.lecousin.reactive.data.relational.query.SelectQuery;
import net.lecousin.reactive.data.relational.repository.LcR2dbcEntityTemplate;
import net.lecousin.reactive.data.relational.schema.RelationalDatabaseSchema;
import net.lecousin.reactive.data.relational.test.arraycolumns.EntityWithArrays;
import net.lecousin.reactive.data.relational.test.simplemodel.DateTypesWithTimeZone;
import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;

@DataR2dbcTest
@EnableAutoConfiguration
Expand Down Expand Up @@ -77,9 +77,9 @@ public void initDatabase() {
protected Collection<Class<?>> getAllCompatibleEntities() {
Collection<Class<?>> entities = new LinkedList<>(EntityStaticMetadata.getClasses());
if (!lcClient.getSchemaDialect().isTimeZoneSupported())
entities.remove(DateTypesWithTimeZone.class);
entities.removeAll(Set.of(DateTypesWithTimeZone.class));
if (!lcClient.getSchemaDialect().isArrayColumnSupported())
entities.remove(EntityWithArrays.class);
entities.removeAll(Set.of(EntityWithArrays.class, UpdateableCollectionProperties.class));
return entities;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package net.lecousin.reactive.data.relational.test.arraycolumns;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import net.lecousin.reactive.data.relational.query.SelectQuery;
import net.lecousin.reactive.data.relational.query.criteria.Criteria;
import net.lecousin.reactive.data.relational.repository.LcR2dbcRepositoryFactoryBean;
import net.lecousin.reactive.data.relational.test.AbstractLcReactiveDataRelationalTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;

import net.lecousin.reactive.data.relational.query.SelectQuery;
import net.lecousin.reactive.data.relational.query.criteria.Criteria;
import net.lecousin.reactive.data.relational.repository.LcR2dbcRepositoryFactoryBean;
import net.lecousin.reactive.data.relational.test.AbstractLcReactiveDataRelationalTest;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;

@EnableR2dbcRepositories(repositoryFactoryBeanClass = LcR2dbcRepositoryFactoryBean.class)
public abstract class AbstractTestArrayColumns extends AbstractLcReactiveDataRelationalTest {
Expand All @@ -22,7 +22,7 @@ public abstract class AbstractTestArrayColumns extends AbstractLcReactiveDataRel

@Override
protected Collection<Class<?>> usedEntities() {
return Arrays.asList(EntityWithArrays.class);
return Arrays.asList(EntityWithArrays.class, UpdateableCollectionProperties.class);
}

@Test
Expand All @@ -33,6 +33,7 @@ public void testEmptyArrays() {
entity = repo1.findAll().blockFirst();
Assertions.assertTrue(entity.getIntegers() == null || entity.getIntegers().length == 0);
Assertions.assertTrue(entity.getPrimitiveIntegers() == null || entity.getPrimitiveIntegers().length == 0);
Assertions.assertTrue(entity.getIntegerList() == null || entity.getIntegerList().size() == 0);
}

@Test
Expand All @@ -58,6 +59,7 @@ public void testArraysWithOneElement() {
entity.setDoubleList(Arrays.asList(4.5d));
entity.setStrings(new String[] { "test1" });
entity.setStringList(Arrays.asList("test2"));
entity.setStringSet(Set.of("test3"));
repo1.save(entity).block();

entity = repo1.findAll().blockFirst();
Expand Down Expand Up @@ -141,6 +143,10 @@ public void testArraysWithOneElement() {
Assertions.assertNotNull(entity.getStringList());
Assertions.assertEquals(1, entity.getStringList().size());
Assertions.assertEquals("test2", entity.getStringList().get(0));

Assertions.assertNotNull(entity.getStringSet());
Assertions.assertEquals(1, entity.getStringSet().size());
Assertions.assertEquals("test3", entity.getStringSet().iterator().next());

// update an element in the array
entity.getIntegers()[0] = 12345;
Expand Down Expand Up @@ -197,4 +203,39 @@ public void testSearchEntityHavingAnArrayContaining() {
.collectList().block();
Assertions.assertEquals(2, list.size());
}

@Test
public void testArraysWithUpdateableCollectionProperties() {
UpdateableCollectionProperties entity = new UpdateableCollectionProperties();
entity.setStrings1(List.of("1.1"));
entity.setStrings2(Set.of("2.1"));
entity.setStrings3(List.of("3.1"));
entity.setStrings4(Set.of("4.1"));

entity = lcClient.save(entity).block();
Assertions.assertEquals(List.of("1.1"), entity.getStrings1());
Assertions.assertEquals(Set.of("2.1"), entity.getStrings2());
Assertions.assertEquals(List.of("3.1"), entity.getStrings3());
Assertions.assertEquals(Set.of("4.1"), entity.getStrings4());
long id = entity.getId();

entity.setStrings1(List.of("1.2"));
entity.setStrings2(Set.of("2.2"));
entity.setStrings3(List.of("3.2"));
entity.setStrings4(Set.of("4.2"));

entity = lcClient.save(entity).block();
Assertions.assertEquals(id, entity.getId());
Assertions.assertEquals(List.of("1.2"), entity.getStrings1());
Assertions.assertEquals(Set.of("2.2"), entity.getStrings2());
Assertions.assertEquals(List.of("3.1"), entity.getStrings3());
Assertions.assertEquals(Set.of("4.1"), entity.getStrings4());

entity = SelectQuery.from(UpdateableCollectionProperties.class, "entity").execute(lcClient).blockFirst();
Assertions.assertEquals(id, entity.getId());
Assertions.assertEquals(List.of("1.2"), entity.getStrings1());
Assertions.assertEquals(Set.of("2.2"), entity.getStrings2());
Assertions.assertEquals(List.of("3.1"), entity.getStrings3());
Assertions.assertEquals(Set.of("4.1"), entity.getStrings4());
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package net.lecousin.reactive.data.relational.test.arraycolumns;

import java.util.List;

import net.lecousin.reactive.data.relational.annotations.GeneratedValue;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;

import net.lecousin.reactive.data.relational.annotations.GeneratedValue;
import java.util.List;
import java.util.Set;

@Table
public class EntityWithArrays {
Expand Down Expand Up @@ -74,6 +74,9 @@ public class EntityWithArrays {
@Column
private List<String> stringList;

@Column
private Set<String> stringSet;

public Long getId() {
return id;
}
Expand Down Expand Up @@ -241,5 +244,12 @@ public List<String> getStringList() {
public void setStringList(List<String> stringList) {
this.stringList = stringList;
}


public Set<String> getStringSet() {
return stringSet;
}

public void setStringSet(Set<String> stringSet) {
this.stringSet = stringSet;
}
}
Loading