问题
I have a project based on jHipster (Java + MongoDB + AngularJS). I am using mongodb with Spring MongoDB repository for data persistance.
Problem is that the same method in repository (called findOneByEntityId) works different in some cases.
Case 1: Angular resource asks controller to fetch TermMap. Controller use method mentioned above. Result is success.
Case 2: DataMapFactory tries to use the same method with the same parameter and get NullPointerException. Result is failure.
Case 3: I've also tried to call controller method from DataMapFactory but it also gives me NullPointerException.
Code of repository:
package com.xxx.yyy.repository;
import com.xxx.yyy.domain.maps.TermsMap;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface TermsMapRepository extends MongoRepository<TermsMap,String> {
    TermsMap findOneByEntityId(String entityId);
}
Code of controller with method (I've stripped non necessary methods)
package com.xxx.yyy.web.rest;
import com.codahale.metrics.annotation.Timed;
import com.xxx.yyy.domain.maps.TermsMap;
import com.xxx.yyy.repository.TermsMapRepository;
import com.xxx.yyy.web.rest.util.HeaderUtil;
import com.xxx.yyy.web.rest.util.PaginationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.inject.Inject;
import javax.validation.Valid;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/api")
public class TermMapResource {
    private final Logger log = LoggerFactory.getLogger(TermMapResource.class);
    @Inject
    private TermsMapRepository tmRepository;
    /**
     * GET  /termmaps/:id -> get the "id" company.
     */
    @RequestMapping(value = "/termmaps/{id}",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public ResponseEntity<TermsMap> getTM(@RequestParam(required = false) String field, @PathVariable String id) {
        switch (field) {
            case "entityId":    log.debug("REST request to get TM by entityId: {}", id);
                                return Optional.ofNullable(tmRepository.findOneByEntityId(id))
                                .map(tm -> new ResponseEntity<>(
                                    tm,
                                    HttpStatus.OK))
                                .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
            default:        log.debug("REST request to get TM : {}", id);
                            return Optional.ofNullable(tmRepository.findOne(id))
                            .map(tm -> new ResponseEntity<>(
                                tm,
                                HttpStatus.OK))
                            .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
        }
    }    
}
Code of repository:
package com.xxx.yyy.domain.factories;
import com.xxx.yyy.domain.maps.TermsMap;
import com.xxx.yyy.repository.TermsMapRepository;
import com.xxx.yyy.web.rest.TermMapResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Optional;
public class DataMapsFactory {
    private static DataMapsFactory instance;
    private final Logger log = LoggerFactory.getLogger(DataMapsFactory.class);
    @Inject
    private TermsMapRepository termsMapRepository;
    public DataMapsFactory(){
    }
    public static DataMapsFactory getInstance(){
        if(instance == null) {
            instance = new DataMapsFactory();
        }
        return instance;
    }
    public ArrayList<String> getDataMapForVehicle(String id) {
        log.debug("Getting data map for: "+id);
        try {
            TermsMap map = termsMapRepository.findOneByEntityId(id);
            log.debug("fetched map: "+map);
            return map.getTermsIds();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
Any help would be very appreciated since I'm pretty stuck at this. If you need any additional information just write :-) Thanks for all answers in advance.
回答1:
As mlk mentioned, problem was with my singleton implementation which caused problem to spring container. I've changed code of DataMapsFactory to:
package com.njugroup.flotilla.domain.factories;
import com.njugroup.flotilla.domain.maps.TermsMap;
import com.njugroup.flotilla.repository.TermsMapRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
public class DataMapsFactory{
    private final Logger log = LoggerFactory.getLogger(TermsMapsFactory.class);
    @Autowired
    private TermsMapRepository termsMapRepository;
    public TermsMap getDataMapForVehicle(String id) {
        log.debug("Getting data map for: "+id);
        try {
            Optional<TermsMap> map = Optional.ofNullable(termsMapRepository.findOneByEntityId(id));
            log.debug("fetched map: "+map);
            return map.get();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
Now it works like a charm.
来源:https://stackoverflow.com/questions/35539757/spring-mongodb-repository-works-only-in-some-cases