我正在学习Spring Data JPA,为此我正在编写Simple独立应用程序。以下是示例代码:
@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
public interface JPADBAccess extends CrudRepository<User, Integer> {
}
@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);
}
}
<?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>
<?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?
答案 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");