Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

Custom Subclasses of Map Cannot be Stored #2334

Closed
ashesfall opened this issue Apr 25, 2020 · 4 comments · Fixed by #2345
Closed

Custom Subclasses of Map Cannot be Stored #2334

ashesfall opened this issue Apr 25, 2020 · 4 comments · Fixed by #2345
Assignees
Labels
datastore GCP Datastore

Comments

@ashesfall
Copy link

ashesfall commented Apr 25, 2020

This section of TwoStepsConversion.java:

	private Value convertOnWrite(Object proppertyVal, EmbeddedType embeddedType,
			String fieldName, TypeInformation typeInformation) {
		Object val = proppertyVal;

		Function<Object, Value> writeConverter = this::convertOnWriteSingle;
		if (proppertyVal != null) {
			switch (embeddedType) {
			case EMBEDDED_MAP:
				writeConverter = (x) -> convertOnWriteSingleEmbeddedMap(x, fieldName,
						(TypeInformation) typeInformation.getTypeArguments().get(1));
				break;
			case EMBEDDED_ENTITY:
				writeConverter = (x) -> convertOnWriteSingleEmbedded(x, fieldName);
				break;
			case NOT_EMBEDDED:
				writeConverter = this::convertOnWriteSingle;
				break;
			default:
				throw new DatastoreDataException(
						"Unexpected property embedded type: " + embeddedType);
			}
		}

		val = ValueUtil.toListIfArray(val);

		if (val instanceof Iterable) {
			List<Value<?>> values = new ArrayList<>();
			for (Object propEltValue : (Iterable) val) {
				values.add(writeConverter.apply(propEltValue));
			}
			return ListValue.of(values);
		}
		return writeConverter.apply(val);
	}

Attempts to obtain type arguments from Maps. However, my custom subclass has no type arguments. It throws the following exception:

java.lang.IndexOutOfBoundsException: Index: 1

	at java.base/java.util.Collections$EmptyList.get(Collections.java:4481)
	at org.springframework.cloud.gcp.data.datastore.core.convert.TwoStepsConversions.lambda$convertOnWrite$2(TwoStepsConversions.java:261)
	at org.springframework.cloud.gcp.data.datastore.core.convert.TwoStepsConversions.convertOnWrite(TwoStepsConversions.java:284)
	at org.springframework.cloud.gcp.data.datastore.core.convert.TwoStepsConversions.convertOnWrite(TwoStepsConversions.java:247)
	at org.springframework.cloud.gcp.data.datastore.core.convert.DefaultDatastoreEntityConverter.lambda$write$3(DefaultDatastoreEntityConverter.java:183)
	at org.springframework.cloud.gcp.data.datastore.core.mapping.DatastorePersistentEntityImpl.lambda$doWithColumnBackedProperties$0(DatastorePersistentEntityImpl.java:206)
	at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:355)
	at org.springframework.cloud.gcp.data.datastore.core.mapping.DatastorePersistentEntityImpl.doWithColumnBackedProperties(DatastorePersistentEntityImpl.java:203)
	at org.springframework.cloud.gcp.data.datastore.core.convert.DefaultDatastoreEntityConverter.write(DefaultDatastoreEntityConverter.java:175)
	at org.springframework.cloud.gcp.data.datastore.core.convert.DefaultDatastoreEntityConverter.write(DefaultDatastoreEntityConverter.java:55)
	at org.springframework.cloud.gcp.data.datastore.core.DatastoreTemplate.convertToEntityForSave(DatastoreTemplate.java:446)
	at org.springframework.cloud.gcp.data.datastore.core.DatastoreTemplate.getEntitiesForSave(DatastoreTemplate.java:163)
	at org.springframework.cloud.gcp.data.datastore.core.DatastoreTemplate.saveEntities(DatastoreTemplate.java:172)
	at org.springframework.cloud.gcp.data.datastore.core.DatastoreTemplate.save(DatastoreTemplate.java:147)
	at org.springframework.cloud.gcp.data.datastore.repository.support.SimpleDatastoreRepository.save(SimpleDatastoreRepository.java:102)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
@meltsufin meltsufin added the datastore GCP Datastore label Apr 27, 2020
@dmitry-s dmitry-s self-assigned this Apr 27, 2020
@dmitry-s
Copy link
Contributor

Hi @ashesfall

could you provide the definition of your custom map class?

Thanks!

@ashesfall
Copy link
Author

public class Configuration extends HashMap<String, Object> {
}

dmitry-s added a commit that referenced this issue May 1, 2020
Datastore - support custom maps; fixes #2334
@ashesfall
Copy link
Author

What release will include this fix?

@meltsufin
Copy link
Contributor

Hoxton.SR5 / 1.2.3 scheduled for May 18th currently.
See: https://github.com/spring-cloud/spring-cloud-release/milestones

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
datastore GCP Datastore
Development

Successfully merging a pull request may close this issue.

3 participants