我使用spring Boot 创建了一个应用程序,它有4种数据库类型:h2,mongodb,redis和neo4j。
我已经实现了h2和mongodb代码。
我将使用aggregatedRating实体示例。
我的逻辑是application.properties中的一个uri,一个包含端点、服务接口、服务实现、AggregatedRatingRepository、AggregatedRatingRepositoryMongo和AggregatedRatingRepositoryImpl的控制器。我还有一个mongoConfig,用于配置Mongo模板。
代码如下:
MongoConfig
package com.isep.acme.config;
import com.isep.acme.model.mongoDomain.*;
import com.isep.acme.repositories.*;
import com.isep.acme.repositories.mongo.*;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import java.lang.reflect.Constructor;
import java.time.LocalDate;
import java.util.Collections;
@Profile("mongo")
@Configuration
@EnableMongoRepositories(basePackages = "com.isep.acme.repositories.mongo")
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
})
public class MongoConfig {
@Value("${spring.data.mongodb.uri}")
private String mongoPrivateUri;
@Bean
public MongoTemplate mongoTemplate() {
return new MongoTemplate(new SimpleMongoClientDatabaseFactory(mongoPrivateUri));
}
}
字符串
AggregatedRatingService
package com.isep.acme.services;
import com.isep.acme.model.AggregatedRating;
public interface AggregatedRatingService {
AggregatedRating save(String sku);
}
型
AggregatedRatingServiceImpl
package com.isep.acme.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.isep.acme.model.AggregatedRating;
import com.isep.acme.model.Product;
import com.isep.acme.repositories.AggregatedRatingRepository;
import com.isep.acme.repositories.ProductRepository;
import java.util.Optional;
@Service
public class AggregatedRatingServiceImpl implements AggregatedRatingService{
@Autowired
AggregatedRatingRepository arRepository;
@Autowired
private ProductRepository pRepository;
@Autowired
ReviewService rService;
@Autowired
ProductService productService;
@Override
public AggregatedRating save( String sku ) {
Optional<Product> product = pRepository.findBySku( sku );
if (product.isEmpty()){
return null;
}
Double average = rService.getWeightedAverage(product.get());
Optional<AggregatedRating> r = arRepository.findByProductId(product.get());
AggregatedRating aggregateF;
if(r.isPresent()) {
r.get().setAverage( average );
aggregateF = (AggregatedRating) arRepository.save(r.get());
}
else {
AggregatedRating f = new AggregatedRating(average, product.get());
aggregateF = (AggregatedRating) arRepository.save(f);
}
return aggregateF;
}
}
型
AggregatedRatingRepository
package com.isep.acme.repositories;
import com.isep.acme.model.Product;
import org.springframework.data.repository.CrudRepository;
import java.util.Optional;
public interface AggregatedRatingRepository<T,L> extends CrudRepository<T, Long>{
Optional<T> findByProductId(Product product);
}
型
AggregatedRatingMongoRepository
package com.isep.acme.repositories.mongo;
import com.isep.acme.model.Product;
import com.isep.acme.model.mongoDomain.AggregatedRatingMongo;
import com.isep.acme.repositories.AggregatedRatingRepository;
import org.springframework.context.annotation.Profile;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import java.util.Optional;
@Profile("mongo")
public interface AggregatedRatingMongoRepository extends AggregatedRatingRepository<AggregatedRatingMongo,Long>, MongoRepository<AggregatedRatingMongo, Long> {
@Query("{'product.sku':?0}")
Optional<AggregatedRatingMongo> findByProductId(Product product);
}
型
AggregatedRatingMongoRepositoryImpl
package com.isep.acme.repositories.mongo.impl;
import com.isep.acme.model.Product;
import com.isep.acme.model.mongoDomain.AggregatedRatingMongo;
import com.isep.acme.repositories.mongo.AggregatedRatingMongoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.query.FluentQuery;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
@Repository
@Profile("mongo")
@Primary
public class AggregatedRatingMongoRepositoryImpl implements AggregatedRatingMongoRepository {
private final AggregatedRatingMongoRepository repo;
@Autowired
public AggregatedRatingMongoRepositoryImpl(@Qualifier("aggregatedRatingMongoRepository") AggregatedRatingMongoRepository aggregatedRatingMongoRepository) {
this.repo = aggregatedRatingMongoRepository;
}
... all the methods implemented by default from mongo (save, saveall, getbyid, etc)
型
我的application.properties看起来像这样:
# swagger-ui custom path
springdoc.api-docs.enabled=true
springdoc.api-docs.path=/api-docs
springdoc.swagger-ui.path=/swagger-ui
## JWT
jwt.private.key=classpath:rsa.private.key
jwt.public.key=classpath:rsa.public.key
spring.datasource.url=jdbc:h2:file:./data/acme;MV_STORE=FALSE;AUTO_SERVER=true;
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=gg
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
# access h2 console at http://localhost:8080/h2-console
spring.jpa.hibernate.ddl-auto=create-drop
## MULTIPART (MultipartProperties)
# Enable multipart uploads
spring.servlet.multipart.enabled=true
# Threshold after which files are written to disk.
spring.servlet.multipart.file-size-threshold=2KB
# Max file size.
spring.servlet.multipart.max-file-size=200MB
# Max Request Size
spring.servlet.multipart.max-request-size=215MB
file.upload-dir=DEV/FileUploads
## Logging
logging.level.com.example.demo=DEBUG
#logging.level.org.springframework=DEBUG
## Profiles
spring.profiles.active=bootstrap,mongo
##Set sku method
sku.creation.method=method1
spring.main.allow-circular-references=true
spring.main.allow-bean-definition-overriding=true
spring.data.mongodb.uri=mongodb+srv://myinfo.mongodb.net/?retryWrites=true&w=majority
spring.data.mongodb.auto-index-creation=true
型
错误:
这里的问题是,我面临这个错误:
2023-11-04 21:14:07.539 ERROR 13436 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
aggregatedRatingController (field com.isep.acme.services.AggregatedRatingService com.isep.acme.controllers.AggregatedRatingController.aService)
↓
aggregatedRatingServiceImpl (field com.isep.acme.repositories.AggregatedRatingRepository com.isep.acme.services.AggregatedRatingServiceImpl.arRepository)
┌─────┐
| aggregatedRatingMongoRepositoryImpl defined in file [C:mylocation\acme\repositories\mongo\impl\AggregatedRatingMongoRepositoryImpl.class]
└─────┘
型
1条答案
按热度按时间8xiog9wr1#
对于初学者来说,你不能将一个引用连接到AggregatedRatingMongoRepository并在同一个类中实现它。这就是给你循环引用运行时错误的原因。
还有,在AggregatedRatingMongoRepositoryImpl中实现自己版本的所有CrudRepository方法对我来说似乎非常奇怪,并且有点代码味道。考虑到实现CrudRepository的全部目的是免费提供所有CRUD操作,而不需要自己实现它们,这似乎非常奇怪。如果你只是在AggregatedRatingRepository中连接而不实现它,你就不必这样做。当你在继承链的更下游实现AggregatedRatingRepository需要你自己实现所有的东西,这是应该避免的。