英文:
Parameter 5 of constructor in ... required a bean of type '...Mapper' that could not be found
问题
Description:
构造函数中的第 5 个参数在 com.example.springmysqlelastic.utils.ElasticSynchronizer 中需要一个类型为 'com.example.springmysqlelastic.mapper.FoodMapper' 的 bean,但找不到该类型的 bean。
Action:
考虑在您的配置中定义一个类型为 'com.example.springmysqlelastic.mapper.FoodMapper' 的 bean。
存在一个将 MySQL 同步到 Elasticsearch 的模块,对于 User 实体一切正常。然后我添加了新的 Food 实体。我设置了文件。但现在我在 FoodMapper 上遇到了 Bean 错误。
项目信息:使用 Spring 在 Elasticsearch 引擎上进行食品、餐厅和用户搜索。
FoodMapper.java
@Mapper(componentModel = "spring")
public interface FoodMapper {
FoodDTO toFoodDTO(Food food);
List<FoodDTO> toFoodDtos(List<Food> foods);
Food toFood(FoodDTO foodDTO);
List<Food> toFoods(List<FoodDTO> foodDTOS);
FoodModel toFoodModel(Food food);
}
UserMapper.java
@Mapper(componentModel = "spring")
public interface UserMapper {
UserDTO toUserDTO(User user);
List<UserDTO> toUserDtos(List<User> users);
User toUser(UserDTO userDTO);
List<User> toUsers(List<UserDTO> userDTOS);
UserModel toUserModel(User user);
}
FoodService.java
@Service
public class FoodService implements IFoodService {
private IFoodDAO foodDAO;
private FoodMapper foodMapper;
@Autowired
public FoodService(IFoodDAO foodDAO, FoodMapper foodMapper) {
this.foodDAO = foodDAO;
this.foodMapper = foodMapper;
}
@Override
public FoodDTO save(FoodDTO foodDTO) {
Food food = this.foodDAO.save(this.foodMapper.toFood(foodDTO));
return this.foodMapper.toFoodDTO(food);
}
@Override
public FoodDTO findById(Long id) {
return this.foodMapper.toFoodDTO(this.foodDAO.findById(id).orElse(null));
}
@Override
public List<FoodDTO> findAll() {
return this.foodMapper.toFoodDtos(this.foodDAO.findAll());
}
}
ElasticSynchronizer.java
@Service
public class ElasticSynchronizer {
private IUserDAO userDAO;
private IUserESRepo userESRepo;
private UserMapper userMapper;
private IFoodDAO foodDAO;
private IFoodESRepo foodESRepo;
private FoodMapper foodMapper;
private static final Logger LOG = LoggerFactory.getLogger(ElasticSynchronizer.class);
@Autowired
public ElasticSynchronizer(IUserDAO userDAO, IUserESRepo userESRepo, UserMapper userMapper, IFoodDAO foodDAO, IFoodESRepo foodESRepo, FoodMapper foodMapper) {
this.userDAO = userDAO;
this.userESRepo = userESRepo;
this.userMapper = userMapper;
this.foodDAO = foodDAO;
this.foodESRepo = foodESRepo;
this.foodMapper = foodMapper;
}
@Scheduled(cron = "0 */3 * * * *")
@Transactional
public void sync() {
LOG.info("开始同步用户 - {}", LocalDateTime.now());
this.syncUsers();
LOG.info("结束同步用户 - {}", LocalDateTime.now());
LOG.info("开始同步食品 - {}", LocalDateTime.now());
this.syncFoods();
LOG.info("结束同步食品 - {}", LocalDateTime.now());
}
private void syncUsers() {
Specification<User> userSpecification = (root, criteriaQuery, criteriaBuilder) ->
getModificationDatePredicate(criteriaBuilder, root);
List<User> userList;
if (userESRepo.count() == 0) {
userList = userDAO.findAll();
} else {
userList = userDAO.findAll(userSpecification);
}
for(User user: userList) {
LOG.info("同步用户 - {}", user.getId());
userESRepo.save(this.userMapper.toUserModel(user));
}
}
private void syncFoods() {
Specification<Food> foodSpecification = (root, criteriaQuery, criteriaBuilder) ->
getModificationDatePredicate(criteriaBuilder, root);
List<Food> foodList;
if (foodESRepo.count() == 0) {
foodList = foodDAO.findAll();
} else {
foodList = foodDAO.findAll(foodSpecification);
}
for(Food food: foodList) {
LOG.info("同步食品 - {}", food.getId());
foodESRepo.save(this.foodMapper.toFoodModel(food));
}
}
private static Predicate getModificationDatePredicate(CriteriaBuilder cb, Root<?> root) {
Expression<Timestamp> currentTime;
currentTime = cb.currentTimestamp();
Expression<Timestamp> currentTimeMinus = cb.literal(new Timestamp(System.currentTimeMillis() -
(Constants.INTERVAL_IN_MILLISECONDS)));
return cb.between(root.<Date>get(Constants.MODIFICATION_DATE),
currentTimeMinus,
currentTime
);
}
}
Food.java
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private float price;
private String category;
private String description;
private String imglink;
private String restaurant;
@Temporal(TemporalType.TIMESTAMP)
@UpdateTimestamp
private Date modificationDate;
}
FoodModel.java
@NoArgsConstructor
@AllArgsConstructor
@Data
@Document(indexName = "food") //type deprecate oldu hepsi artik _doc
public class FoodModel {
private Long id;
private String name;
private float price;
private String category;
private String description;
private String imglink;
private String restaurant;
private Date modificationDate;
}
FoodDTO.java
@NoArgsConstructor
@AllArgsConstructor
@Data
public class FoodDTO {
private Long id;
private String name;
private float price;
private String category;
private String description;
private String imglink;
private String restaurant;
}
IFoodDAO.java
@Repository
public interface IFoodDAO extends JpaRepository<Food, Long>, JpaSpecificationExecutor<Food> {
//List<User> findByNameContaining(String name);
}
IFoodESRepo.java
public interface IFoodESRepo extends ElasticsearchRepository<FoodModel, Long> {
//List<Food> findByNameContaining(String name);
}
main class
@SpringBootApplication
@EnableElasticsearchRepositories("com.example.springmysqlelastic.repo.elastic")
@EnableScheduling
@EnableJpaRepositories("com.example.springmysqlelastic.repo")
//@ComponentScan(basePackages = {"com.example.springmysqlelastic"})
//@EnableAutoConfiguration
public class SpringMysqlElasticApplication {
public static void main(String[] args) {
SpringApplication.run(SpringMysqlElasticApplication.class, args);
}
}
结构
![enter image description
英文:
Description:
Parameter 5 of constructor in com.example.springmysqlelastic.utils.ElasticSynchronizer required a bean of type 'com.example.springmysqlelastic.mapper.FoodMapper' that could not be found.
Action:
Consider defining a bean of type 'com.example.springmysqlelastic.mapper.FoodMapper' in your configuration.
There is a MySQL to Elasticsearch sync module and all was working for User entity. Then i added new Food entity. I set files. But now im getting Bean error on FoodMapper.
Project info: food, restaurant, user search on Elasticsearch engine with Spring.
FoodMapper.java
@Mapper(componentModel = "spring")
public interface FoodMapper {
FoodDTO toFoodDTO(Food food);
List<FoodDTO> toFoodDtos(List<Food> foods);
Food toFood(FoodDTO foodDTO);
List<Food> toFoods(List<FoodDTO> foodDTOS);
FoodModel toFoodModel(Food food);
}
UserMapper.java
@Mapper(componentModel = "spring")
public interface UserMapper {
UserDTO toUserDTO(User user);
List<UserDTO> toUserDtos(List<User> users);
User toUser(UserDTO userDTO);
List<User> toUsers(List<UserDTO> userDTOS);
UserModel toUserModel(User user);
}
FoodService.java
@Service
public class FoodService implements IFoodService {
private IFoodDAO foodDAO;
private FoodMapper foodMapper;
@Autowired
public FoodService(IFoodDAO foodDAO, FoodMapper foodMapper) {
this.foodDAO = foodDAO;
this.foodMapper = foodMapper;
}
@Override
public FoodDTO save(FoodDTO foodDTO) {
Food food = this.foodDAO.save(this.foodMapper.toFood(foodDTO));
return this.foodMapper.toFoodDTO(food);
}
@Override
public FoodDTO findById(Long id) {
return this.foodMapper.toFoodDTO(this.foodDAO.findById(id).orElse(null));
}
@Override
public List<FoodDTO> findAll() {
return this.foodMapper.toFoodDtos(this.foodDAO.findAll());
}
}
ElasticSynchorizer.java
@Service
public class ElasticSynchronizer {
private IUserDAO userDAO;
private IUserESRepo userESRepo;
private UserMapper userMapper;
private IFoodDAO foodDAO;
private IFoodESRepo foodESRepo;
private FoodMapper foodMapper;
private static final Logger LOG = LoggerFactory.getLogger(ElasticSynchronizer.class);
@Autowired
public ElasticSynchronizer(IUserDAO userDAO, IUserESRepo userESRepo, UserMapper userMapper, IFoodDAO foodDAO, IFoodESRepo foodESRepo, FoodMapper foodMapper) {
this.userDAO = userDAO;
this.userESRepo = userESRepo;
this.userMapper = userMapper;
this.foodDAO = foodDAO;
this.foodESRepo = foodESRepo;
this.foodMapper = foodMapper;
}
@Scheduled(cron = "0 */3 * * * *")
@Transactional
public void sync() {
LOG.info("Start Syncing Users - {}", LocalDateTime.now());
this.syncUsers();
LOG.info(" End Syncing Users - {}", LocalDateTime.now());
LOG.info("Start Syncing Foods- {}", LocalDateTime.now());
this.syncFoods();
LOG.info(" End Syncing Foods - {}", LocalDateTime.now());
}
private void syncUsers() {
Specification<User> userSpecification = (root, criteriaQuery, criteriaBuilder) ->
getModificationDatePredicate(criteriaBuilder, root);
List<User> userList;
if (userESRepo.count() == 0) {
userList = userDAO.findAll();
} else {
userList = userDAO.findAll(userSpecification);
}
for(User user: userList) {
LOG.info("Syncing User - {}", user.getId());
userESRepo.save(this.userMapper.toUserModel(user));
}
}
private void syncFoods() {
Specification<Food> userSpecification = (root, criteriaQuery, criteriaBuilder) ->
getModificationDatePredicate(criteriaBuilder, root);
List<Food> foodList;
if (userESRepo.count() == 0) {
foodList = foodDAO.findAll();
} else {
foodList = foodDAO.findAll(userSpecification);
}
for(Food food: foodList) {
LOG.info("Syncing Food - {}", food.getId());
foodESRepo.save(this.foodMapper.toFoodModel(food));
}
}
private static Predicate getModificationDatePredicate(CriteriaBuilder cb, Root<?> root) {
Expression<Timestamp> currentTime;
currentTime = cb.currentTimestamp();
Expression<Timestamp> currentTimeMinus = cb.literal(new Timestamp(System.currentTimeMillis() -
(Constants.INTERVAL_IN_MILLISECONDE)));
return cb.between(root.<Date>get(Constants.MODIFICATION_DATE),
currentTimeMinus,
currentTime
);
}
}
Food.java
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private float price;
private String category;
private String description;
private String imglink;
private String restaurant;
@Temporal(TemporalType.TIMESTAMP)
@UpdateTimestamp
private Date modificationDate;
}
Foodmodel.java
@NoArgsConstructor
@AllArgsConstructor
@Data
@Document(indexName = "food") //type deprecate oldu hepsi artik _doc
public class FoodModel {
private Long id;
private String name;
private float price;
private String category;
private String description;
private String imglink;
private String restaurant;
private Date modificationDate;
}
FoodDTO.java
@NoArgsConstructor
@AllArgsConstructor
@Data
public class FoodDTO {
private Long id;
private String name;
private float price;
private String category;
private String description;
private String imglink;
private String restaurant;
}
IFoodDAO.java
@Repository
public interface IFoodDAO extends JpaRepository<Food, Long>, JpaSpecificationExecutor<Food> {
//List<User> findByNameContaining(String name);
}
IFoodESRepo.java
public interface IFoodESRepo extends ElasticsearchRepository<FoodModel, Long> {
//List<Food> findByNameContaining(String name);
}
main class
@SpringBootApplication
@EnableElasticsearchRepositories("com.example.springmysqlelastic.repo.elastic")
@EnableScheduling
@EnableJpaRepositories("com.example.springmysqlelastic.repo")
//@ComponentScan(basePackages = {"com.example.springmysqlelastic"})
//@EnableAutoConfiguration
public class SpringMysqlElasticApplication {
public static void main(String[] args) {
SpringApplication.run(SpringMysqlElasticApplication.class, args);
}
}
structure
enter image description here
enter image description here
答案1
得分: 1
我发现我不能使用多个映射器。将第二个映射器移到第一个现在可以使用。
不要使用多于一个映射器。
英文:
I found that i can't use multiple mappers. Moved second mapper to first now works.
Don't use more than 1 mapper.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论