【问题标题】:Spring MongoDB Repository works only in some casesSpring MongoDB Repository 仅在某些情况下有效
【发布时间】:2016-02-21 17:58:27
【问题描述】:

我有一个基于 jHipster (Java + MongoDB + AngularJS) 的项目。我正在将 mongodb 与 Spring MongoDB 存储库一起用于数据持久性。

问题是存储库中的相同方法(称为 findOneByEntityId)在某些情况下工作方式不同。

案例 1: Angular 资源要求控制器获取 TermMap。控制器使用方法如上。结果是成功。

案例 2: DataMapFactory 尝试使用具有相同参数的相同方法并获得 NullPointerException。结果是失败。

案例 3: 我也尝试从 DataMapFactory 调用控制器方法,但它也给了我 NullPointerException。

存储库代码:

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);
}

带有方法的控制器代码(我已经剥离了不必要的方法)

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));
        }
    }    
}

存储库代码:

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;

        }
    }
}

任何帮助将不胜感激,因为我非常坚持这一点。 如果您需要任何其他信息,请写:-) 提前感谢所有答案。

【问题讨论】:

  • 我没用过spring,所以也许它比我习惯的更有魔力,但看起来DataMapsFactory是一个自制的单身人士,Spring不知道。我以为 Spring 默认是单例的,那为什么要这样做呢?如果它是一个自制的单例,那么它永远不会注入TermsMapRepository。我个人会转向构造函数注入,它会突出显示这一点。
  • 非常感谢您的建议。我已经删除了单件零件并从 spring 中使用了 DI。现在它就像一个魅力。

标签: java spring mongodb jhipster


【解决方案1】:

正如mlk 所提到的,问题出在我的单例实现上,导致弹簧容器出现问题。我已将DataMapsFactory 的代码更改为:

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;

        }
    }
}

现在它就像一个魅力。

【讨论】:

    猜你喜欢
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    相关资源
    最近更新 更多