Skip to content
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

Fix null pointer issue when typeKey is set as null #685

Merged
merged 1 commit into from
Jan 8, 2024

Conversation

avi054
Copy link

@avi054 avi054 commented Jan 5, 2024

When a custom bean of AerospikeTypeAliasAccessor is created passing null in the constructor(for skipping the typeKey to be saved in aerospike)
eg:

@Bean
public AerospikeTypeAliasAccessor aerospikeTypeAliasAccessor() {
    return new AerospikeTypeAliasAccessor(null);
}

While saving there is null check in writeTypeTo method to safely skip saving the typeKey if its passed as null, but in case of readAliasFrom it will throw NullPointerException, so added null check.

When a custom bean of AerospikeTypeAliasAccessor is created passing null in the constructor(for skipping the typeKey to be saved in aerospike)
eg:
@bean
public AerospikeTypeAliasAccessor aerospikeTypeAliasAccessor() {
    return new AerospikeTypeAliasAccessor(null);
}    
While saving there is null check in writeTypeTo method to safely skip saving the typeKey if its passed as null, but in case of readAliasFrom it will throw NullPointerException, so added null check.
@avi054
Copy link
Author

avi054 commented Jan 6, 2024

How can I add a label to this pull request?

@reugn reugn added the bug label Jan 6, 2024
@reugn
Copy link
Member

reugn commented Jan 6, 2024

@avi054, added.

@avi054 avi054 changed the title fixed null pointer issue when typeKey is set as null Fixed null pointer issue when typeKey is set as null Jan 6, 2024
@roimenashe
Copy link
Member

Hi @avi054 thanks for contributing to Spring Data Aerospike!

I tried to override aerospikeTypeAliasAccessor bean, save and read the object and everything seems to work and I couldn't reproduce NullPointerException - I tested on Spring Data Aerospike version 4.6.0.

When calling readAliasFrom, return Alias.ofNullable(source.get(typeKey)); actually returns Alias.NONE in case the typeKey is null (debugged it).

typeKey = null -> source.get(typeKey) returns null -> Alias.ofNullable(null) returns Alias.NONE.

Can you please share the rest of the code and the exact record you have in your database that resulted in NPE? I think this check might be redundant since its already being checked when calling Alias.ofNullable().

Also worth mentioning:
Removing @_class bin is a risky operation, disabling saving type information will make it impossible to read documents with generic data types, check out Anastasiia comment on: https://stackoverflow.com/questions/68292496/spring-aerospike-data-how-to-remove-user-key-and-class-bins-from-sets

@avi054
Copy link
Author

avi054 commented Jan 7, 2024

Hi @roimenashe ,

Null pointer will be thrown by sources.get(null), that's why the check is necessary.
As you can see from the java documentation below.
image

@roimenashe
Copy link
Member

roimenashe commented Jan 7, 2024

@avi054 That's Map interface documentation but null handling depends on the implementation, when reading from Aerospike we use forRead() under the hood which gets Aerospike Record and translates it into a Map, by default a LinkedHashMap will be selected which doesn't throw NullPointerException when passing a null to the get() method but returns a null instead.

Can you provide the exact case that resulted in a NPE?

@avi054
Copy link
Author

avi054 commented Jan 7, 2024

Hi @roimenashe ,

LinkedHashMap is only used for bins, but when we stored a list of nested objects, internally it is unpacked as a ArrayList of TreeMap.
You can refer the Unpacker.java for that:
image
image

@roimenashe roimenashe requested review from roimenashe and reugn January 7, 2024 17:02
@roimenashe
Copy link
Member

@avi054 I see, thanks for catching this and sorry for the trouble - I just wanted to verify what cases exactly you are aiming to fix, approving.

Please wait until @reugn approves as well and we will merge

@avi054
Copy link
Author

avi054 commented Jan 7, 2024

Sample code to reproduce:

@Bean
public AerospikeTypeAliasAccessor aerospikeTypeAliasAccessor() {
    return new AerospikeTypeAliasAccessor(null);
}
import org.springframework.data.aerospike.repository.AerospikeRepository;

public interface TestRepo extends AerospikeRepository<TestEntity,Long> {
}
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.aerospike.mapping.Field;

@Getter
@Setter
@AllArgsConstructor
public class TestAddress {

    @Field("street")
    private String street;
    @Field("pin")
    private String pin;

}

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.aerospike.mapping.Document;
import org.springframework.data.aerospike.mapping.Field;
import org.springframework.data.annotation.Id;

import java.util.List;

@Getter
@Setter
@Document(collection = TestEntity.SET_NAME)
public class TestEntity {
    @JsonIgnore
    public static final String SET_NAME = "d_test";

    @Id
    @Field("id")
    private Long id;

    @Field("address")
    List<TestAddress> address;

}

public TestEntity postTest() {
    TestEntity entity = new TestEntity();
    entity.setId(1001L);
    entity.setAddress(List.of(new TestAddress("street1", "1234"),
            new TestAddress("street1", "1234")));
    return testRepo.save(entity);
}


public TestEntity getTest() {
    Optional<TestEntity> byId = testRepo.findById(1001L);
    return byId.get();
}

Sample json:
{
"id": 1001,
"address": [
{
"street": "street1",
"pin": "1234"
},
{
"street": "street1",
"pin": "1234"
}
]
}

Copy link
Member

@reugn reugn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @avi054.
@agrgr, need to cover this case in unit tests.

@reugn reugn changed the title Fixed null pointer issue when typeKey is set as null Fix null pointer issue when typeKey is set as null Jan 7, 2024
@reugn reugn merged commit 436b96e into aerospike:main Jan 8, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants