Spring Data JPA如何选择/识别基础JPA Provider?

时间:2016-05-05 18:49:58

标签: spring hibernate spring-data spring-data-jpa

我正在学习Spring Data JPA,为此我正在编写Simple独立应用程序。以下是示例代码:

实体类 - > User.java

@Entity
@Table(name="USER_DETAILS")
public class User {
    @Id
    @Column(name="SSNID")
    private int ssnID;
    @Column(name="FULLNAME")
    private String fullName;
    @Column(name="CITY")
    private String city;
    // Getters and Setters omitted
}

Repository类 - > JPADBAccess.java

@Repository
    public interface JPADBAccess extends CrudRepository<User, Integer> {

    }

使用存储库的简单服务类 - &gt; DBServices.java

@Service
public class DBServices {

    @Autowired(required=true)
    private JPADBAccess jPADBAccess;  // How does this work?? ---->(1)

    public void saveUser(User user) {

        User queriedUser = null;
        jPADBAccess.save(user);

    }
}

Spring配置文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans ... ">

<context:annotation-config/> <!-- This enables the annotation's actions, else annotations don't do their work. -->
<context:component-scan base-package="com.example.service"/> <!-- This is for component scan -->

<jpa:repositories base-package="com.example.jpa"/> <!-- This enables support for Spring Data JPA. -->

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
      <property name="dataSource" ref="dataSource"/>
      <property name="jpaVendorAdapter">
         <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
             <property name="showSql" value="true"/>
             <property name="generateDdl" value="true"/>
          </bean>
      </property>
 </bean>

 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="org.h2.Driver"/>
      <property name="url" value="jdbc:h2:tcp://localhost:9092/~/test"/>
      <property name="username" value="sa"/>
      <property name="password" value=""/>
 </bean>

 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
       <property name="entityManagerFactory" ref="entityManagerFactory"/>
 </bean>

persistence.xml如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
    <persistence-unit name="userPersistenceUnit" transaction-type="RESOURCE_LOCAL" >
    <class>com.example.model.User</class>
</persistence-unit>

独立类看起来像这样:

public class MainApp {
    public static void main(String s[]) {
        DBServices dBServices = null;
        User user = new User();
        user.setSsnID(1);
        user.setCity("Blr");
        user.setFullName("Full name");
        ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-config.xml");
        dBServices = (DBServices) appContext.getBean("DBServices");
        dBServices.saveUser(user);
    }
}

现在一切正常,我使用Hibernate作为JPA提供程序(只需将jar放在类路径中)

我有以下问题:

1)当配置文件中没有定义bean时,DBService如何通过@Autowire获取JPADBAccess实例。

    @Autowired(required=true)
    private JPADBAccess jPADBAccess;  // How does this work?? ---->(1)

2)如果在任何配置文件中没有提到Hibernate,Spring Data JPA如何使用或推断底层JPA提供程序是Hibernate?

2 个答案:

答案 0 :(得分:2)

  

1)当配置文件中没有定义bean时,DBService如何通过@Autowire获取JPADBAccess实例。

这是Spring Data JPA的神奇之处:它找到了你的存储库接口并自动生成它的实现,它被放在Spring应用程序上下文中。在您自动装配JPADBAccess的类中,Spring会找到自动生成的实现。

  

2)如果在任何配置文件中没有提到Hibernate,Spring Data JPA如何使用或推断底层JPA提供程序是Hibernate?

但是,在entityManagerFactory中你指定了一个HibernateJpaVendorAdapter bean。

答案 1 :(得分:1)

<jpa:repositories base-package="com.example.jpa"/>

该行扫描所有存储库并为您创建bean,在这种情况下,您创建了名为JPADBAccess的bean,并且创建了实现的spring数据,因此您不需要编写任何代码行,并添加到应用程序上下文中。

提供者的选择取决于类路径,JPA使用一些类来选择提供者,如下所示

有时在类路径中搜索文件META-INF/services/javax.persistence.spi.PersistenceProvider,并且会有提供商的名称,在您使用HibernateJpaVendorAdapter的情况下,在class code中您会看到这行加载hibernate作为提供者

Class<?> hibernatePersistenceProviderClass = cl.loadClass("org.hibernate.jpa.HibernatePersistenceProvider");