Skip to content

Spring boot: 3.2.0, Spring data Couchbase: 5.2.0: java.lang.IllegalArgumentException: Attribute of type java.util.Collections.SingletonList cannot be stored and must be converted. #1875

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ilangranet opened this issue Dec 10, 2023 · 17 comments · Fixed by #1883
Labels
status: waiting-for-triage An issue we've not yet triaged

Comments

@ilangranet
Copy link

Hi,

I am using Spring boot: 3.2.0 with Spring data Couchbase: 5.2.0

I have an entity defined with a field of type Object (this field can be everything (String or List...)):

public class Person {
    @NotNull
    @Id
    private String id;

    @NotNull
    @Field
    private String name;

    @Field
    private int age;

    @Field
    private Object myObject;
}

while trying to save it using this:
personRepository.save(new Person("1", "Alice", 25, Collections.singletonList("my issue")));

It failed on java.lang.IllegalArgumentException: Attribute of type java.util.Collections.SingletonList cannot be stored and must be converted.

it was working with previous version: Spring boot: 2.7.13, Spring data Couchbase: 4.4.13.
demo.zip

Find attached the project where it failed: to reproduce, run PersonRepositoryTest

Any suggestion?

Thank you

@mikereiche
Copy link
Collaborator

This should work and I'll fix it. In the meantime, you might try a JsonArray instead of a List

@ilangranet
Copy link
Author

ilangranet commented Dec 10, 2023

This should work and I'll fix it. In the meantime, you might try a JsonArray instead of a List

I tried and get the same issue:
java.lang.IllegalArgumentException: Attribute of type com.couchbase.client.java.json.JsonArray cannot be stored and must be converted.

@mikereiche
Copy link
Collaborator

I haven't investigated this yet, but this is more likely the issue. How is Object supposed to be serialized? Deserialized? What constructor should be used?

@Field
private Object myObject;

@roman-sinyakov
Copy link

@mikereiche this is a regression in v5. Could you make it work like it used to be in v4 ?

@mikereiche
Copy link
Collaborator

mikereiche commented Dec 12, 2023

The issue is that conversion.isSimpleType() considers Object to be a simple type, while the

MappingCouchbaseConverter

if (!conversions.isSimpleType(prop.getType())) {
	writePropertyInternal(propertyObj, target, prop, accessor);
} else {
	writeSimpleInternal(prop, accessor, target, prop.getFieldName());
}

While verifyValue (called from target.put() called from writeSimpleInternal()) does not consider it to be a simpletype.
CouchbaseDocument

private void verifyValueType(final Object value) {
	if (value == null) {
		return;
	}
	final Class<?> clazz = value.getClass();
	if (CouchbaseSimpleTypes.DOCUMENT_TYPES.isSimpleType(clazz)) {
		return;
	}
	throw new IllegalArgumentException(
			"Attribute of type " + clazz.getCanonicalName() + " cannot be stored and must be converted.");
}

@mikereiche
Copy link
Collaborator

mikereiche commented Dec 12, 2023

@roman-sinyakov

this is a regression in v5. Could you make it work like it used to be in v4 ?

I can make the serialization (save) work. But it appears that the deserialization (findById etc), did not work in v4 and won't work in v5 without other changes.

The breaking change is in MappingCouchbaseConverter.java. old line 579 vs new line 616 - propertyObj.getClass() (the object) vs prop.getType() (the field on the class)

deca246#diff-ed94230cdca258107738571365038a574bfe8d12f6b1fef0dea3ca4f6b19507fL579

@mikereiche
Copy link
Collaborator

@roman-sinyakov @ilangranet - are you ok with saving working, but reading (still) not working?

@ilangranet
Copy link
Author

@roman-sinyakov @ilangranet - are you ok with saving working, but reading (still) not working?

with spring data 4.x, save and read were working.
we still need both.

@mikereiche
Copy link
Collaborator

I thought I tried reading with 4.x and it didn't work. I'll look again

@ilangranet
Copy link
Author

ilangranet commented Dec 17, 2023

I tried with spring boot 2.7.13, which brings

<dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-couchbase</artifactId>
      <version>4.4.13</version>
      <scope>compile</scope>
</dependency>

PersonRepositoryTest.java.zip

it worked both save and read.

@mikereiche
Copy link
Collaborator

Thanks. I'll investigate on Monday.

@mikereiche
Copy link
Collaborator

@ilangranet - I can't get the read to work in 4.4.x or in anything else. Since the field type is Object, it doesn't have a componentType (line 766).
So when readCollection() is called at line 776 with componentType==null, it throws an exception because it does not accept a null targetType.

https://github.com/spring-projects/spring-data-couchbase/blob/061f7ab8ed530ecd9337b7d56bfcabba194729f6/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java#L755:L783

@korkutkose
Copy link

@mikereiche Hi, I've just run across to this issue on starter-data-couchbase 3.2.2 with data-couchbase 5.2.2.
I see that this has been merged to 5.2.x and main branch already.
When will it be shipped, any plans?
Any workarounds you'd suggest until that time rather than rolling back?
Thanks.

@mikereiche
Copy link
Collaborator

Tomorrow. https://calendar.spring.io/

@umeshmishra099
Copy link

Hi,
We getting same issue with starter-data-couchbase 3.4.3 with data-couchbase 5.4.3

@mikereiche
Copy link
Collaborator

Please provide details.

@umeshmishra099
Copy link

it was working Spring boot: [3.2.4]
demo_3_2.zip
it fails with Spring boot: [3.4.3]
demo_3_4.zip

Step to test

  1. Run spring boot application
  2. Run this curl
    curl --location --request POST 'http://localhost:8080/api/testpojo/create'
    --header 'Content-Type: application/json'
    --data-raw '{
    "field1": "value55",
    "field2": [{
    "locale": "en-US",
    "value": "test data11"
    }],
    "field3": "value3",
    "field4": "value4",
    "field5": "value5"
    }'
  3. it fails for spring boot 3.4.3 with error java.lang.IllegalArgumentException: Attribute of type java.util.ArrayList cannot be stored and must be converted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants