基于Spring开发Telegram食谱Bot时遇Bean与EntityManagerFactory错误
食谱类Telegram Bot连接MySQL时的EntityManagerFactory Bean错误排查
问题描述
使用Spring框架开发食谱类Telegram Bot,项目包含以下组件:
- User实体:含chatId(主键)、userName、firstName、lastName、registeredAt字段
- UserRepository:继承CrudRepository
- BotConfig:含botName、token、ownerId字段
- BotInitializer、TelegramBot服务类
连接MySQL数据库时,出现Bean依赖注入失败,核心错误为NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available。
相关代码
BotInitializer
@Slf4j @Component public class BotInitializer { @Autowired TelegramBot tgBot; @EventListener({ContextRefreshedEvent.class}) public void init() throws TelegramApiException { TelegramBotsApi telegramBotsApi = new TelegramBotsApi(DefaultBotSession.class); try{ telegramBotsApi.registerBot(tgBot); } catch (TelegramApiException e) { log.error("Error occurred: " + e.getMessage()); } } }
TelegramBot服务类
@Slf4j @Component public class TelegramBot extends TelegramLongPollingBot { @Autowired private UserRepository userRepository; final BotConfig botConfig; static final String HELP_TEXT = "This bot is created to help find recipes for cooking delicious foods."; public TelegramBot(BotConfig botConfig, UserRepository userRepository) { this.botConfig = botConfig; List<BotCommand> commandList = new ArrayList<>(); commandList.add(new BotCommand("/start", "start communicating with bot")); commandList.add(new BotCommand("/help", "help info")); commandList.add(new BotCommand("/category", "category of recipes")); commandList.add(new BotCommand("/find", "search recipe by name")); commandList.add(new BotCommand("/random", "random recipe")); try { this.execute(new SetMyCommands(commandList, new BotCommandScopeDefault(), null)); } catch (TelegramApiException e) { log.error("Error setting bots command list: " + e.getMessage()); } } @Override public String getBotUsername() { return botConfig.getBotName(); } @Override public String getBotToken() { return botConfig.getToken(); } @Override public void onUpdateReceived(Update update) { if(update.hasMessage() && update.getMessage().hasText()) { String messageText = update.getMessage().getText(); long chatId = update.getMessage().getChatId(); switch (messageText) { case "/start": registerNewUser(update.getMessage()); handleStartCommand(chatId, update.getMessage().getChat().getFirstName()); break; case "/help" : sendMessage(chatId, HELP_TEXT); break; default: sendMessage(chatId, "Command was not recognized"); } } } private void registerNewUser(Message message) { if(userRepository.findById(message.getChatId()).isEmpty()) { var chatId = message.getChatId(); var chat = message.getChat(); User user = new User(); user.setChatId(chatId); user.setUserName(chat.getUserName()); user.setFirstName(chat.getFirstName()); user.setLastName(chat.getLastName()); user.setRegisteredAt(new Timestamp(System.currentTimeMillis())); userRepository.save(user); log.info("User " + user.getUserName() + " is saved"); } } public void handleStartCommand(long chatId, String userName) { String answer = "Hi, " + userName + " nice to meet you!"; log.info("Replied to user " + userName + " after getting start command."); sendMessage(chatId, answer); } private void sendMessage(long chatId, String textToSend) { SendMessage message = new SendMessage(); message.setChatId(String.valueOf(chatId)); message.setText(textToSend); try { execute(message); } catch (TelegramApiException e) { log.error("Error occurred: " + e.getMessage()); } } }
application.properties
bot.name=goldenRecipes bot.token=Token bot.owner=OwnerId spring.jpa.hibernate.ddl-auto=update spring.datasource.url=jdbc:mysql://localhost:3307/golden-recipes-bot spring.datasource.username=dbusername spring.datasource.password=dbpass spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect spring.jpa.show-sql=true
报错信息(中文翻译)
org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为'botInitializer'的Bean时出错:通过字段'tgBot'表达的依赖不满足; 嵌套异常是org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为'telegramBot'的Bean时出错(定义在文件[D:\goldenRecipesBot\target\classes\io\project\goldenRecipesBot\service\TelegramBot.class]): 通过构造器参数1表达的依赖不满足; 嵌套异常是org.springframework.beans.factory.BeanCreationException: 创建名为'userRepository'的Bean时出错(定义在io.project.goldenRecipesBot.repository.UserRepository,由@EnableJpaRepositories声明在JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration): 设置Bean属性'entityManager'时无法创建类型为[org.springframework.orm.jpa.SharedEntityManagerCreator]的内部Bean'(inner bean)#6bd16207'; 嵌套异常是org.springframework.beans.factory.BeanCreationException: 创建名为'(inner bean)#6bd16207'的Bean时出错:设置构造器参数时无法解析对'entityManagerFactory'的引用; 嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException: 找不到名为'entityManagerFactory'的Bean at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:659) ...(省略后续重复栈信息)
解决方案
1. 确认依赖完整性
确保项目中引入了Spring Data JPA和MySQL驱动的依赖,EntityManagerFactory由Spring Data JPA自动配置,缺少依赖会导致无法创建该Bean。
Maven依赖示例:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency>
2. 检查包扫描范围
确保Spring Boot主启动类的@SpringBootApplication注解覆盖了Repository和实体类所在的包。如果组件分布在子包,可显式指定扫描路径:
@SpringBootApplication @EnableJpaRepositories(basePackages = "io.project.goldenRecipesBot.repository") @EntityScan(basePackages = "io.project.goldenRecipesBot.entity") public class GoldenRecipesBotApplication { public static void main(String[] args) { SpringApplication.run(GoldenRecipesBotApplication.class, args); } }
3. 验证数据库配置
- 确认MySQL服务正在运行,端口3307(默认是3306)正确,数据库
golden-recipes-bot已创建。 - 检查
spring.datasource.username和spring.datasource.password是否与MySQL账号匹配。 - 确认
spring.jpa.database-platform与MySQL版本匹配(MySQL 8.x使用MySQL8Dialect,低版本需调整为对应Dialect)。
4. 检查User实体注解
确保User实体类添加了@Entity注解,主键字段添加@Id注解,否则JPA无法识别实体,导致EntityManagerFactory创建失败:
@Entity @Table(name = "users") public class User { @Id private Long chatId; private String userName; private String firstName; private String lastName; private Timestamp registeredAt; // Getter和Setter方法 }
5. 清理缓存并重建项目
执行清理命令清除编译缓存,再重新构建项目:
- Maven:
mvn clean install - Gradle:
./gradlew clean build
内容的提问来源于stack exchange,提问作者Асем Маратбек
相关产品推荐
相关产品推荐

