配置H2数据源为何需显式设置包扫描?如何复用@Entity Bean?
一、为什么必须显式设置包扫描?
当你通过LocalContainerEntityManagerFactoryBean手动配置JPA实体管理器工厂时,Spring需要明确知道去哪里查找带有@Entity注解的实体类。默认情况下,它会尝试读取META-INF/persistence.xml文件获取持久化单元配置,但你没有提供这个文件,因此必须通过setPackagesToScan指定实体类所在的包路径。
如果不设置包扫描,JPA无法发现EmployeeEntity这类实体类,就会抛出No persistence units parsed from {classpath*:META-INF/persistence.xml}错误——因为它找不到任何可管理的实体,无法生成有效的持久化单元。
二、如何复用@Entity注解标记的实体相关能力?
注意:@Entity注解本身不会将类注册为Spring Bean,它只是标记该类为JPA实体。若要在Spring上下文里复用实体的操作能力,可通过以下方式:
1. 使用Spring Data JPA Repository(推荐)
创建继承JpaRepository的接口,Spring会自动生成实现类,通过Repository即可便捷操作实体:
import org.springframework.data.jpa.repository.JpaRepository; import com.practice.demo.entity.EmployeeEntity; public interface EmployeeRepository extends JpaRepository<EmployeeEntity, Long> { }
之后在Service或其他Spring Bean中注入该Repository,就能复用实体的CRUD等操作。
2. 注入EntityManager操作实体
在Spring Bean中注入EntityManager,通过它管理实体的生命周期(持久化、查询等):
import javax.persistence.EntityManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class EmployeeService { @Autowired private EntityManager entityManager; public void saveEmployee(EmployeeEntity employee) { entityManager.persist(employee); } }
3. 手动注册实体为Bean(不推荐)
如果确实需要将实体类本身作为Spring Bean,可在配置类中添加:
@Bean public EmployeeEntity employeeEntity() { return new EmployeeEntity(); }
但这种方式意义不大,因为实体类通常与数据库记录一一对应,操作时一般需要创建新实例,而非复用单例Bean。
额外优化提示
EmployeeEntity上的@EnableAutoConfiguration注解多余,应删除——该注解用于Spring Boot自动配置,放在实体类上无作用。- H2内存库URL写法有误,正确格式应为
jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1,你多写的:9090会导致连接失败,内存库无需指定端口。
内容的提问来源于stack exchange,提问作者Subhajit

