0

Im using spring and lombok to reduce code clutter.

Currently I have a code in my entity/model class that would throw a default value of "01" if a null is detected

@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@NonNull
@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public final class CreditCardDetails {

    @JsonAlias("ax21:returnCde")
    @NonNull private String returnCde;

    @JsonAlias("ax21:cif")
    private String cif;

    @JsonAlias("ax21:creditCardType")
    private String creditCardType;

    @JsonAlias("ax21:expiryDate")
    private String expiryDate;

    public String getReturnCde() {
        if(returnCde==null){
            returnCde="01";
        }
        return returnCde;
    }
}

However, I'm still getting NPEs even though this getReturnCde method should always return a string value of 01 if it got a null value. How do I prevent this param from throwing a null value or NPE?.

iamjoshua
  • 1,157
  • 3
  • 16
  • 33
  • 1
    `private String returnCde="01";` - also, what if `CreditCardDetails` itself is a null instance? How are you calling this? – Elliott Frisch Oct 14 '21 at 08:28
  • 1
    'Throw a default value of "01"' is meaningless. Exceptions are thrown: values are returned. Don't misuse standard terminology. Duplicate. – user207421 Oct 14 '21 at 08:35
  • 1
    You would have to show us the code where such an NPE is thrown - we can't tell from this code here. `getReturnCde()` won't return `null` , so the problem is somewhere else. (unless you call this in multithreaded code and might be set to `null` from another thread - it is not thread-safe). – Hulk Oct 14 '21 at 08:37
  • doesnt work with private String returnCde="01" either – iamjoshua Oct 14 '21 at 08:52
  • 1
    Thanks @Hulk , you input allowed me to fix the issue. Apparently it is indeed located somewhere. So what I did is set the value to 01 from the higher level class /model since the higher level class is the original one throwing the NPE before the class where returnCde parameter is located. Just waiting for this to be re-opened to provide the full code that fixed it. No wonder I know the code somehow should work, but otherwise is still throwing NPE, I indeed missed the earlier instance of where the null value occured. – iamjoshua Oct 14 '21 at 09:14
  • NOTE TO REVIEWERS: The question is about particularities of _spring framework_'s modeling, not understanding what is an NPE. The proposed duplicate doesn't help here. – James Oct 15 '21 at 15:57
  • 1
    @iamjoshua Looks like this has been reopened, so you can now add the code that fixed it as an answer. – M. Justin Oct 16 '21 at 04:38
  • Thanks, for re-opening, I posted the scenario and the code that fixed mine. Thanks again for @Hulk for the recommendation. – iamjoshua Oct 18 '21 at 06:50

1 Answers1

0

So for the fix.

This is where I am getting an NPE initially when my conditional flow below executes.

if (getCreditCardResponseJson.getEnvelop().getBody().getResponse().getDetails().getReturnCde()
                .equals(CreditCardStatus.VALID_CARD.getCode()))

In the debug logs, I could see that it is getting a null value from the getReturnCde code.

Hence I assumed that just assigning a default value on it when it throws a null would be fine, apparently, I also need to assign or set its value from the higher level class where this model is being retrieved as that model class also has a null value.

So instead of doing the above code I asked in the question, I did it on the higher class with the first null thrown at first.

@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public final class GetCreditCardInfo {

    @JsonAlias("ns:return")
    private CreditCardDetails details;

    @SuppressWarnings("checkstyle:RegexpSingleline")
    public CreditCardDetails getDetails() {
        if (details == null) {
            final CreditCardDetails creditCardDetails = new CreditCardDetails();
            creditCardDetails.setReturnCde("01");
            return creditCardDetails;
        }

        return details;
    }
}

The code above is the class where the json payload is being serialized and assigned to JAVA POJOs. And this is is the higher level class where the **.getReturnCde() is being set.

In summary, I assumed the fixed on NPE would be at CreditCardDetails class but apparently it is not.

As I have to set the null value from the higher level model class named GetCreditCardInfo which also calls the CreditCardDetails class which also happens to throw a null value.

So in my case, I have two model classes that throws a null named GetCreditCardInfo and CreditCardDetails. My initial fix only fixed the issue CreditCardDetails and hence it is still throwing an NPE, the fix is to address the initial null thrown from the higher level class named GetCreditCardInfo as pointed by @Hulk in the comments here. So thanks. My problem is now fixed.

iamjoshua
  • 1,157
  • 3
  • 16
  • 33