0

While implementing OData V4 using Olingo in Java, I am getting a NullPointerException.

Here is a detailed description --

Trying to implement OData V4 using olingo in Java in my Spring Boot application. I am following the official documentation https://olingo.apache.org/doc/odata4/tutorials/readep/tutorial_readep.html

Rather than feeding the data manually/static data, I am using a database that is providing the data.

As per the documentation, I have created a class Storage.java to simulate the data layer.

public class Storage {

@Autowired
CompanyService cservice;


private List<Entity> companyentityList;

public Storage() throws Exception {
    companyentityList = new ArrayList<Entity>();
    initSampleData();
}

// PUBLIC FACADE

public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet) throws NullPointerException {

    // actually, this is only required if we have more than one Entity Sets
    if (edmEntitySet.getName().equals(DemoEdmProvider.ES_COMPANY_RECORDS)) {
        return getCompaniesData();
    }

    return null;
}

public Entity readEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams) throws Exception {

    EdmEntityType edmEntityType = edmEntitySet.getEntityType();

    // actually, this is only required if we have more than one Entity Type
    if (edmEntityType.getName().equals(DemoEdmProvider.ET_COMPANY)) {
        return getCompany(edmEntityType, keyParams);
    }

    return null;
}

// INTERNAL

public EntityCollection getCompaniesData() throws NullPointerException {
    EntityCollection retEntitySet = new EntityCollection();

    for (Entity companyEntity : this.companyentityList) {
        retEntitySet.getEntities().add(companyEntity);
    }

    return retEntitySet;
}

public Entity getCompany(EdmEntityType edmEntityType, List<UriParameter> keyParams) throws Exception {

    // the list of entities at runtime
    EntityCollection entitySet = getCompaniesData();

    // generic approach to find the requested entity
    Entity requestedEntity = Util.findEntity(edmEntityType, entitySet, keyParams);

    if (requestedEntity == null) {
        // this variable is null if our data doesn't contain an entity for the requested
        // key
        // Throw suitable exception
        throw new ODataApplicationException("Entity for requested key doesn't exist",
                HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
    }

    return requestedEntity;
}

// Helper

public void initSampleData() {

    
    try {
        getData();
    } catch (NullPointerException e) {
        System.out.print("<<<<<<<---------------- Database unable to provide data ------------>>>>>>");
    }
}

public List<Company> getAllcompanyList() {
    Collection<Company> checkingdata = new ArrayList<>();
    try {
          checkingdata = cservice.getDetails();

    } catch (NullPointerException e) {
        System.out.print("<<<<<<<---------------- Database unable to provide data ------------>>>>>>");
    }
    return  (List<Company>) checkingdata;
}

// final EntityCollection entitySet = new EntityCollection();
// loop over List<Company> converting each instance of Company into and Olingo Entity
public EntityCollection makeEntityCollection(List<Company> companyList) {

    EntityCollection entitySet = new EntityCollection();
    for (Company cmp : companyList) {
        entitySet.getEntities().add(createEntity(cmp));
    }

    return entitySet;
}

// Convert instance of cmp object into an Olingo Entity
public Entity createEntity(Company cmp) {
    final Entity tmpEntity = new Entity().addProperty(new Property(null, "ID", ValueType.PRIMITIVE, cmp.getId()))
            .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, cmp.getContent()));
    companyentityList.add(tmpEntity);
    return tmpEntity;
}

public void getData() throws NullPointerException {
    // ... code to get Data from the DataBase in List and calling makeEntityCollection

    List<Company> companyList = getAllcompanyList();
    makeEntityCollection(companyList);
    // System.out.println(companyList.size());

}

}

In the above mentioned code I @Autowired the CompanyService interface reference cservice.

Here is the implementation of CompanyService -

public interface CompanyService {

 Collection<Company> getDetails() throws Exception;

}

CompanyService interface is implemented by CompanyServiceImplementation -

@Service
public class CompanyServiceImplementation implements CompanyService{

@Autowired
private  CompanyDAOImplementation cDAOWrapper;

public Collection<Company> getDetails() throws Exception {
    
    return cDAOWrapper.findAll();
}

}

In the above class, the findAll() method is returning the data from the database.

So the problem is that - The CompanyService reference cservice which is @Autowired in Storage.java class is null and it is not getting initialised and hence I am getting a NullPointerException while calling cservice.getDetails().

Please let me know what is wrong with my Code. Thanks in advance.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
Alchemist
  • 1
  • 1
  • 1
    Please add the full stack trace of your exception to your question. – tgdavies Mar 31 '21 at 05:52
  • 4
    I think the problem is that you are calling methods in your constructor, before the CompanyService has been injected. – tgdavies Mar 31 '21 at 05:53
  • 1
    @tgdavies is right. Put the code from the constructor into a method that is annotated with `@PostConstruct`. Then remove your constructor. Additionally, I do not see any `@Component` annotation on your class `Storage` ... – Seelenvirtuose Mar 31 '21 at 05:57
  • Sorry. My Bad. Thanks @tgdavies. – Alchemist Mar 31 '21 at 06:18
  • That won't work. The `Storage` comes from the database and isn't a spring managed bean. So using `@Autowired` on that will not work. This is kind of a duplicate of https://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null (see also https://deinum.biz/2020-07-03-Autowired-Field-Null/). – M. Deinum Mar 31 '21 at 06:42
  • @M.Deinum It worked. And yes, Storage was not a Spring managed bean earlier but now I annotated it with `@Component` and autowired it and, now it works. – Alchemist Apr 01 '21 at 06:36

0 Answers0