-
Notifications
You must be signed in to change notification settings - Fork 192
fix issue with id in nested objects caused by DATACOUCH-533 [DATACOUCH-620] #928
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
Comments
Martin commented This issue is still not fixed in 4.0.5. When I read document from CB the ids are always null. Document
{
"embedded": [
{
"id": "9Hc6nb7T",
"title": "Test",
"embedded": [
{
"id": "4fw8cfw5",
"title": "Embedded in embedded"
}
]
}
],
"name": "Embedded Id test",
"_class": "com.example.EmbeddedIdParent"
} Entity
public class EmbeddedIdParent {
public static final String PREFIX = "t";
@IdPrefix
private String prefix = PREFIX;
@Id
@GeneratedValue(strategy = GenerationStrategy.UNIQUE, delimiter = "_")
private String id;
@Field
private String name;
@Field
private List<Embedded> embedded = new ArrayList<>();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Embedded> getEmbedded() {
return embedded;
}
public void setEmbedded(List<Embedded> embedded) {
this.embedded = embedded;
}
public static class Embedded {
private String id;
private String title;
private List<Embedded> embedded;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<Embedded> getEmbedded() {
return embedded;
}
public void setEmbedded(List<Embedded> embedded) {
this.embedded = embedded;
}
}
}
|
Michael Reiche commented Hi martin8877 - I reproduced this. I will fix it. If you create a constructor that takes the 'id' as an argument, or an all-args constructor for Embedded, the issue will be avoided. public Embedded( String id){ public Embedded( String id, String title, List<Embedded> embedded){ |
Michael Reiche commented fix does not work unless a constructor using the 'id' as an arg was used. line 264 in MappingCouchbaseConverter needs to check if parent == null Object obj = prop.isIdProperty() && parent != null ? source.getId() : getValueInternal(prop, source, instance); |
Martin commented I tried to extend MappingCouchbaseConverter and override read method with suggested fix (parent == null, not parent != null) @Override
protected <R> R read(CouchbasePersistentEntity<R> entity, CouchbaseDocument source, Object parent) {
R instance = super.read(entity, source, parent);
final ConvertingPropertyAccessor accessor = getPropertyAccessor(instance);
entity.doWithProperties(new PropertyHandler<CouchbasePersistentProperty>() {
@Override
public void doWithPersistentProperty(final CouchbasePersistentProperty prop) {
if (!doesPropertyExistInSource(prop) || entity.isConstructorArgument(prop) || isIdConstructionProperty(prop)
|| prop.isAnnotationPresent(N1qlJoin.class)) {
return;
}
Object obj = prop.isIdProperty() && parent == null ? source.getId() : getValueInternal(prop, source, instance);
accessor.setProperty(prop, obj);
}
private boolean doesPropertyExistInSource(final CouchbasePersistentProperty property) {
return property.isIdProperty() || source.containsKey(property.getFieldName());
}
private boolean isIdConstructionProperty(final CouchbasePersistentProperty property) {
return property.isAnnotationPresent(IdPrefix.class) || property.isAnnotationPresent(IdSuffix.class);
}
});
return instance;
}
private ConvertingPropertyAccessor<Object> getPropertyAccessor(Object source) {
CouchbasePersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(source.getClass());
PersistentPropertyAccessor<Object> accessor = entity.getPropertyAccessor(source);
return new ConvertingPropertyAccessor<>(accessor, conversionService);
} It looks like it works but I don't like it cause it's ugly and not very effective I guess. I will wait for fix. Thank you |
Hi, |
Just as info, we updated our project to Spring Boot 2.3.7 (Spring Data Couchbase 4.0.6 released on December) and still facing same issue when retrieving embedded object id. In the meantime as a workaround we applied @mikereiche approach using an all-args constructor for the embedded object. |
The fix is available now in 4.2-SNAPSHOT, if I understand how SNAPSHOT works correctly.
MappingCouchbaseConverter - Line 270 |
Michael Reiche opened DATACOUCH-620 and commented
DATACOUCH-533 assumes fields named 'id' are document id's. As such they are removed from the data to be used as the "key".
When a nested document - such as Submission in the User object - contains an 'id', it is also removed from the data.
public class User {
private String id;
private String username;
private List<Submission> submissions;
}
public class Submission {
private final String id;
private final String userId;
private final String talkId;
}
Referenced from: pull request #266
Backported to: 4.0.5 (Neumann SR5)
1 votes, 3 watchers
The text was updated successfully, but these errors were encountered: