MongoRepository Save 方法不插入数据库

Posted

技术标签:

【中文标题】MongoRepository Save 方法不插入数据库【英文标题】:MongoRepository Save method does not insert in database 【发布时间】:2021-09-19 07:15:28 【问题描述】:

我用 Jhipster 创建了一个 SpringBoot 项目。我使用的数据库是 MongoDB。

在 application-dev.yml 我有以下配置:

data:
mongodb:
  uri: mongodb://<user>:<pass>@<ip>:<port>
  database: gateway

我的应用程序开发中的用户、密码、ip地址和端口是真实值。

DatabaseConfiguration.java 是:

@Configuration
@EnableMongoRepositories("es.second.cdti.repository")
@Profile("!" + JHipsterConstants.SPRING_PROFILE_CLOUD)
@Import(value = MongoAutoConfiguration.class)
@EnableMongoAuditing(auditorAwareRef = "springSecurityAuditorAware")
public class DatabaseConfiguration 

    private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);

    @Bean
    public ValidatingMongoEventListener validatingMongoEventListener() 
        return new ValidatingMongoEventListener(validator());
    

    @Bean
    public LocalValidatorFactoryBean validator() 
        return new LocalValidatorFactoryBean();
    

    @Bean
    public MongoCustomConversions customConversions() 
        List<Converter<?, ?>> converters = new ArrayList<>();
        converters.add(DateToZonedDateTimeConverter.INSTANCE);
        converters.add(ZonedDateTimeToDateConverter.INSTANCE);
        return new MongoCustomConversions(converters);
    

    @Bean
    public Mongobee mongobee(MongoClient mongoClient, MongoTemplate mongoTemplate, MongoProperties mongoProperties) 
        log.debug("Configuring Mongobee");
        Mongobee mongobee = new Mongobee(mongoClient);
        mongobee.setDbName(mongoProperties.getMongoClientDatabase());
        mongobee.setMongoTemplate(mongoTemplate);
        // package to scan for migrations
        mongobee.setChangeLogsScanPackage("es.second.cdti.config.dbmigrations");
        mongobee.setEnabled(true);
        return mongobee;
    

CloudDatabaseConfiguration 是:

@Configuration
@EnableMongoRepositories("es.second.cdti.repository")
@Profile(JHipsterConstants.SPRING_PROFILE_CLOUD)
public class CloudDatabaseConfiguration extends AbstractCloudConfig 

    private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class);

    @Bean
    public MongoDbFactory mongoFactory() 
        return connectionFactory().mongoDbFactory();
    

    @Bean
    public LocalValidatorFactoryBean validator() 
        return new LocalValidatorFactoryBean();
    

    @Bean
    public ValidatingMongoEventListener validatingMongoEventListener() 
        return new ValidatingMongoEventListener(validator());
    

    @Bean
    public MongoCustomConversions customConversions() 
        List<Converter<?, ?>> converterList = new ArrayList<>();
        converterList.add(DateToZonedDateTimeConverter.INSTANCE);
        converterList.add(ZonedDateTimeToDateConverter.INSTANCE);
        converterList.add(DurationToLongConverter.INSTANCE);
        return new MongoCustomConversions(converterList);
    

    @Bean
    public Mongobee mongobee(MongoDbFactory mongoDbFactory, MongoTemplate mongoTemplate, Cloud cloud) 
        log.debug("Configuring Cloud Mongobee");
        List<ServiceInfo> matchingServiceInfos = cloud.getServiceInfos(MongoDbFactory.class);

        if (matchingServiceInfos.size() != 1) 
            throw new CloudException("No unique service matching MongoDbFactory found. Expected 1, found "
                + matchingServiceInfos.size());
        
        MongoServiceInfo info = (MongoServiceInfo) matchingServiceInfos.get(0);
        Mongobee mongobee = new Mongobee(info.getUri());
        mongobee.setDbName(mongoDbFactory.getDb().getName());
        mongobee.setMongoTemplate(mongoTemplate);
        // package to scan for migrations
        mongobee.setChangeLogsScanPackage("es.second.cdti.config.dbmigrations");
        mongobee.setEnabled(true);
        return mongobee;
    

cdtiApp.java 是:

@SpringBootApplication
@EnableConfigurationProperties(ApplicationProperties.class)
public class CdtiApp  implements InitializingBean

    private static final Logger log = LoggerFactory.getLogger(CdtiApp.class);

    private final Environment env;

    public CdtiApp(Environment env) 
        this.env = env;
    

    /**
     * Initializes cdti.
     * <p>
     * Spring profiles can be configured with a program argument --spring.profiles.active=your-active-profile
     * <p>
     * You can find more information on how profiles work with JHipster on <a href="https://www.jhipster.tech/profiles/">https://www.jhipster.tech/profiles/</a>.
     */
    @PostConstruct
    public void initApplication() 
        Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
        if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) 
            log.error("You have misconfigured your application! It should not run " +
                "with both the 'dev' and 'prod' profiles at the same time.");
        
        if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)) 
            log.error("You have misconfigured your application! It should not " +
                "run with both the 'dev' and 'cloud' profiles at the same time.");
        
    

    /**
     * Main method, used to run the application.
     *
     * @param args the command line arguments.
     */
    public static void main(String[] args) 
        SpringApplication app = new SpringApplication(CdtiApp.class);
        DefaultProfileUtil.addDefaultProfile(app);
        Environment env = app.run(args).getEnvironment();
        logApplicationStartup(env);
    

    private static void logApplicationStartup(Environment env) 
        String protocol = "http";
        if (env.getProperty("server.ssl.key-store") != null) 
            protocol = "https";
        
        String serverPort = env.getProperty("server.port");
        String contextPath = env.getProperty("server.servlet.context-path");
        if (StringUtils.isBlank(contextPath)) 
            contextPath = "/";
        
        String hostAddress = "localhost";
        try 
            hostAddress = InetAddress.getLocalHost().getHostAddress();
         catch (UnknownHostException e) 
            log.warn("The host name could not be determined, using `localhost` as fallback");
        
        log.info("\n----------------------------------------------------------\n\t" +
                "Application '' is running! Access URLs:\n\t" +
                "Local: \t\t://localhost:\n\t" +
                "External: \t://:\n\t" +
                "Profile(s): \t\n----------------------------------------------------------",
            env.getProperty("spring.application.name"),
            protocol,
            serverPort,
            contextPath,
            protocol,
            hostAddress,
            serverPort,
            contextPath,
            env.getActiveProfiles());

        String configServerStatus = env.getProperty("configserver.status");
        if (configServerStatus == null) 
            configServerStatus = "Not found or not setup for this application";
        
        log.info("\n----------------------------------------------------------\n\t" +
                "Config Server: \t\n----------------------------------------------------------", configServerStatus);
    

    @Override
    public void afterPropertiesSet() throws Exception 
        // TODO Auto-generated method stub
        
    

车辆实体:

@org.springframework.data.mongodb.core.mapping.Document(collection = "vehicle")
public class Vehicle implements Serializable 
    
    private static final long serialVersionUID = 1L;

    @Id
    private String id;
    
    @NotNull
    @Field("plate")
    private String plate;
    
    @NotNull
    @Field("registrationDate")
    private Instant registrationDate;
    
    @NotNull
    @Field("brand")
    private String brand;
    
    @NotNull
    @Field("model")
    private String model;

    public String getId() 
        return id;
    

    public void setId(String id) 
        this.id = id;
    

    public String getPlate() 
        return plate;
    

    public void setPlate(String plate) 
        this.plate = plate;
    

    public Instant getRegistrationDate() 
        return registrationDate;
    

    public void setRegistrationDate(Instant registrationDate) 
        this.registrationDate = registrationDate;
    

    public String getBrand() 
        return brand;
    

    public void setBrand(String brand) 
        this.brand = brand;
    

    public String getModel() 
        return model;
    

    public void setModel(String model) 
        this.model = model;
        


VehicleDTO 是:

public class VehicleDTO 

    private String id;
    
    private String plate;
    
    private Instant registrationDate;
    
    private String brand;
    
    private String model;

    public String getId() 
        return id;
    

    public void setId(String id) 
        this.id = id;
    

    public String getPlate() 
        return plate;
    

    public void setPlate(String plate) 
        this.plate = plate;
    

    public Instant getRegistrationDate() 
        return registrationDate;
    

    public void setRegistrationDate(Instant registrationDate) 
        this.registrationDate = registrationDate;
    

    public String getBrand() 
        return brand;
    

    public void setBrand(String brand) 
        this.brand = brand;
    

    public String getModel() 
        return model;
    

    public void setModel(String model) 
        this.model = model;
    
    
    

VehicleMapper 是:

@Mapper(componentModel = "spring")
public interface VehicleMapper

    Vehicle toEntity(VehicleDTO source);
    VehicleDTO toDto(Vehicle target);

VehicleResource 是:

@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "*", methods =  RequestMethod.GET, RequestMethod.POST )
public class VehicleResource 

    private final Logger log = LoggerFactory.getLogger(VehicleResource.class);

    @Value("$jhipster.clientApp.name")
    private String applicationName;

    @Autowired
    private final VehicleService vehicleService;

    public VehicleResource(VehicleService vehicleService) 
        this.vehicleService = vehicleService;
    

    @PostMapping("/vehicle")
    @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
    public ResponseEntity<Vehicle> createVehicle(@Valid @RequestBody VehicleDTO vehicleDTO) throws URISyntaxException 
        log.debug("REST request to save Vehicle : ", vehicleDTO);

        Vehicle newVehicle = vehicleService.createVehicle(vehicleDTO);

        return ResponseEntity.created(new URI("/api/vehicle/" + newVehicle.getPlate()))
                .headers(HeaderUtil.createAlert(applicationName, "vehicleManagement.created", newVehicle.getPlate()))
                .body(newVehicle);

    

VehicleService 接口是:

public interface VehicleService 

    Vehicle createVehicle(VehicleDTO vehicleDTO);

VehicleServiceImpl 是:

@Service
public class VehicleServiceImpl implements VehicleService
    
    @Autowired
    private final VehicleRepository vehicleRepository;
    
    @Autowired
    private final VehicleMapper mapper;
        
    public VehicleServiceImpl(VehicleRepository vehicleRepository, VehicleMapper mapper) 
        this.vehicleRepository = vehicleRepository;
        this.mapper = mapper;
    

    private final Logger log = LoggerFactory.getLogger(VehicleServiceImpl.class);

    @Override
    public Vehicle createVehicle(VehicleDTO vehicleDTO) 
        
        Vehicle vehicle = vehicleRepository.save(mapper.toEntity(vehicleDTO));
        log.debug("Created Information for vehicle: ", vehicle);
        
        return vehicle; 
    
    


VehicleRepository 接口是:

/**
 * Spring Data MongoDB repository for the @link Vehicle entity.
 */
@Repository
public interface VehicleRepository extends MongoRepository<Vehicle, String> 


我从 Swagger 控制台访问 Vehicle-Resource: Swagger console

单击按钮并在文本框中写入带有车辆数据的 json: enter JSON data

如下图所示,答案是 201。最初,车辆使用标识符“id”保存:“60e740935ed5a10e2c2ed19e”。 Send request

我访问数据库以检查车辆是否已正确存储在车辆表中。令我惊讶的是......车辆表中没有车辆: show database

我可以确定数据库application-dev中的数据是OK的。我没有任何其他数据库。

我怀疑实际上并未进行与数据库的交易。这些数据以某种方式存储在内存中,因为如果我从 Swagger 执行 findAllVehicles,它确实会返回车辆。

【问题讨论】:

【参考方案1】:

我有一个正在运行的 eureka 服务器(jhipster-registry)和两个与之同步的微服务。网关,充当反向代理和 Vehiculos 微服务。 Swagger 控制台是网关,我从那里发出插入车辆的请求。一切似乎都正常,但正如我在 bbdd 中所说的那样,并没有保存任何东西。

【讨论】:

以上是关于MongoRepository Save 方法不插入数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何防止从我的MongoRepository导出某些HTTP方法?

使用 Spring Data MongoRepository 进行更新查询的自定义方法

MongoRepository动态代理及jpa方法解析源码分析

MongoRepository怎么修改数据

使用Spring Data Mongodb的MongoRepository类进行增删改查

对于用u盘安装CentOS后不插u盘就无法开启的解决过程