You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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,提问作者Асем Маратбек

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 21:25:23