【问题标题】:How to configure Spring without persistence.xml?如何在没有 persistence.xml 的情况下配置 Spring?
【发布时间】:2025-12-24 13:50:16
【问题描述】:

我正在尝试设置 spring xml 配置,而不必再创建一个 persistence.xml。但是我经常遇到以下异常,即使我将数据库属性包含在 spring.xml

    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in file [C:\Users\me\workspace\app\src\main\webapp\WEB-INF\applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: No persistence units parsed from {classpath*:META-INF/persistence.xml}

spring.xml:

  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
  </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
     <property name="jpaProperties">
         <props>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
         </props>
      </property>
    </bean>

我在这里错过了什么?

【问题讨论】:

    标签: java spring hibernate jpa configuration


    【解决方案1】:

    来自弹簧指南Accessing Data with JPA

    @Configuration
    @EnableJpaRepositories
    public class Application {
    
        @Bean
        public DataSource dataSource() {
            return new EmbeddedDatabaseBuilder().setType(H2).build();
        }
    
        @Bean
        public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
            LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
            lef.setDataSource(dataSource);
            lef.setJpaVendorAdapter(jpaVendorAdapter);
            lef.setPackagesToScan("hello");
            return lef;
        }
    
        @Bean
        public JpaVendorAdapter jpaVendorAdapter() {
            HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
            hibernateJpaVendorAdapter.setShowSql(false);
            hibernateJpaVendorAdapter.setGenerateDdl(true);
            hibernateJpaVendorAdapter.setDatabase(Database.H2);
            return hibernateJpaVendorAdapter;
        }
    

    春季启动

    使用启用 Spring Boot 的应用程序会更容易:

    示例application.yaml

    spring:
        datasource:
            url: jdbc:h2:mem:test
            username: sa
            password: sa
            driver-class-name: org.h2.Driver
        jpa:
            database: H2
            show-sql: false
            hibernate:
                format_sql: true
                ddl-auto: auto
    

    【讨论】:

    【解决方案2】:

    在 entityManagerFactory bean 定义中指定“packagesToScan”和“persistenceUnitName”属性。

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="dataSource" ref="dataSource" />
    
            <property name="persistenceUnitName" value="myPersistenceUnit" />
            <property name="packagesToScan" >
                <list>
                    <value>org.mypackage.*.model</value>
                </list>
            </property>
    
            <property name="jpaProperties">
                <props>
                    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                    <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                    <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                    <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                </props>
            </property>
        </bean>
    

    请注意,这是针对 Spring 版本 > 3.1

    【讨论】:

    • 您是否知道以您需要的相同方式配置复合持久单元及其成员而无需persistence.xml文件。
    • 它是否允许我们使用 spring 加载 entityManager,例如:@PersistenceContext private EntityManager em;
    • 我得到“在 EntityManagerConfiguration 中没有指定持久性提供程序...”异常。你在回答中错过了吗?
    • 有什么用,'myPersistenceUnit'在哪里存在??
    • 但这是一个 xml 配置!
    【解决方案3】:

    MariuszS 的回答很好,只是 entityManagerFactory 方法应该返回 EntityManagerFactory。为此,可以这样写:

    @Bean
    public EntityManagerFactory entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource);
        lef.setJpaVendorAdapter(jpaVendorAdapter);
        lef.setPackagesToScan("hello");
        return lef.object();
    }
    

    对于未来的观众:以下代码有效:

    @Bean (name = "entityManagerFactory")
    public EntityManagerFactory entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter)
    {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource);
        lef.setJpaVendorAdapter(jpaVendorAdapter);
        lef.setPackagesToScan("*.models*");
        lef.afterPropertiesSet(); // It will initialize EntityManagerFactory object otherwise below will return null
        return lef.getObject();
    }
    

    【讨论】:

      【解决方案4】:

      假设你有一个PersistenceProvider 实现(例如org.hibernate.jpa.HibernatePersistenceProvider),你可以使用PersistenceProvider#createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) 方法来引导一个EntityManagerFactory 而不需要persistence.xml

      但是,您必须实现 PersistenceUnitInfo 接口很烦人,因此您最好使用 Spring 或 Hibernate,它们都支持在没有 persistence.xml 文件的情况下引导 JPA。

      this.nativeEntityManagerFactory = provider.createContainerEntityManagerFactory(
          this.persistenceUnitInfo, 
          getJpaPropertyMap()
      );
      

      PersistenceUnitInfo 由 Spring 特定的 MutablePersistenceUnitInfo 类实现。

      【讨论】:

        最近更新 更多