Spring 使用 Spring 数据 JPA 启动
Spring Boot with Spring Data JPA
环境:
Spring 引导 1.4.0.RELEASE
代码:
我有一个简单的 Spring REST
Web 服务设置如下:
Spring 数据 JPA Dao 层:
public interface UserDao extends JpaRepository<User,Long>{
}
Spring 服务层:
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
public void saveUser(User user){
userDao.save(user);
}
}
Spring 控制器:
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/user", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public void saveUser(@RequestBody User user){
this.userService.saveUser(user);
}
}
pom.xml 摘录:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Issue/Queries :
当我调用 UserController.saveUser 时进行上述设置,一切正常,数据被保存到数据库中。我在内存中使用 H2 db .
所以我的问题是:
1)我的服务层没有标记 @Transactional
也没有使用任何 AOP 配置?
那么creating/managing这里的交易是谁?
调试应用程序后,似乎 Spring Data JPA Repository class 具有 AOPProxy CGLIB
语义?
这意味着这个 class 是 运行 inside transaction 。
如果我们不将 Spring 服务设置为 @Transactional
,这是默认行为吗?
2)当使用 Spring 引导时,以下所有内容都会根据 classpath 自动为您配置:
1)DataSource
2)Transaction Manager
如果是这种情况,我看过几个教程,其中持久性配置包含以下内容:
为什么这是必需的呢?
Spring boot 不应该自动为您配置以下所有内容吗?
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.atul.domain" });
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.username"));
dataSource.setPassword(env.getProperty("jdbc.password"));
return dataSource;
}
@Bean
public JpaTransactionManager transactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
1) Spring 默认情况下,数据会围绕对存储库方法的调用创建事务(参见 http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions)。所以,如果你的服务层没有标记@Transactional
,默认情况下每个存储库调用都会有自己的事务(这在很多情况下是不可取的)。
2) 只有在默认值不能满足您的需要时才需要这个额外的配置代码。在您的代码示例中,我没有看到您无法使用 Spring 引导功能进行配置的任何内容,因此实际上并不需要这些额外的代码。
环境:
Spring 引导 1.4.0.RELEASE
代码:
我有一个简单的 Spring REST
Web 服务设置如下:
Spring 数据 JPA Dao 层:
public interface UserDao extends JpaRepository<User,Long>{
}
Spring 服务层:
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
public void saveUser(User user){
userDao.save(user);
}
}
Spring 控制器:
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/user", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public void saveUser(@RequestBody User user){
this.userService.saveUser(user);
}
}
pom.xml 摘录:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Issue/Queries :
当我调用 UserController.saveUser 时进行上述设置,一切正常,数据被保存到数据库中。我在内存中使用 H2 db .
所以我的问题是:
1)我的服务层没有标记 @Transactional
也没有使用任何 AOP 配置?
那么creating/managing这里的交易是谁?
调试应用程序后,似乎 Spring Data JPA Repository class 具有 AOPProxy CGLIB
语义?
这意味着这个 class 是 运行 inside transaction 。
如果我们不将 Spring 服务设置为 @Transactional
,这是默认行为吗?
2)当使用 Spring 引导时,以下所有内容都会根据 classpath 自动为您配置:
1)DataSource
2)Transaction Manager
如果是这种情况,我看过几个教程,其中持久性配置包含以下内容: 为什么这是必需的呢? Spring boot 不应该自动为您配置以下所有内容吗?
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.atul.domain" });
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.username"));
dataSource.setPassword(env.getProperty("jdbc.password"));
return dataSource;
}
@Bean
public JpaTransactionManager transactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
1) Spring 默认情况下,数据会围绕对存储库方法的调用创建事务(参见 http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions)。所以,如果你的服务层没有标记@Transactional
,默认情况下每个存储库调用都会有自己的事务(这在很多情况下是不可取的)。
2) 只有在默认值不能满足您的需要时才需要这个额外的配置代码。在您的代码示例中,我没有看到您无法使用 Spring 引导功能进行配置的任何内容,因此实际上并不需要这些额外的代码。