Tôi đã tạo một ứng dụng Khởi động mùa xuân bằng phiên bản 1.2.0 với spring-boot-starter-data-jpa và tôi đang sử dụng MySQL. Tôi đã định cấu hình các thuộc tính MySQL của mình trong tệp application.properties một cách chính xác.Khởi động mùa xuân + Dữ liệu mùa xuân JPA + Giao dịch không hoạt động đúng cách
Tôi có một JPA Entity đơn giản, Spring liệu JPA Repository và một dịch vụ như sau:
@Entity
class Person
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
//setters & getters
}
@Repository
public interface PersonRepository extends JpaRepository<Person, Integer>{
}
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
class PersonService
{
@Autowired PersonRepository personRepository;
@Transactional
void save(List<Person> persons){
for (Person person : persons) {
if("xxx".equals(person.getName())){
throw new RuntimeException("boooom!!!");
}
personRepository.save(person);
}
}
}
Tôi có thử nghiệm JUnit sau:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class ApplicationTests {
@Autowired
PersonService personService;
@Test
public void test_logging() {
List<Person> persons = new ArrayList<Person>();
persons.add(new Person(null,"abcd"));
persons.add(new Person(null,"xyz"));
persons.add(new Person(null,"xxx"));
persons.add(new Person(null,"pqr"));
personService.save(persons);
}
}
Kỳ vọng ở đây là nó không nên chèn bất kỳ bản ghi nào vào bảng PERSON vì nó sẽ ném Ngoại lệ trong khi chèn đối tượng thứ 3. Nhưng nó không được quay trở lại, 2 hồ sơ đầu tiên được đưa vào và cam kết.
Sau đó, tôi đã nghĩ nhanh chóng thử với Trình quản lý thực thể JPA.
@PersistenceContext
private EntityManager em;
em.save(person);
Sau đó, tôi nhận được javax.persistence.TransactionRequiredException: Không EntityManager giao dịch có sẵn ngoại lệ.
Sau khi googling đôi khi tôi gặp chủ đề JIRA này https://jira.spring.io/browse/SPR-11923 về cùng một chủ đề.
Sau đó, tôi đã cập nhật phiên bản Spring Boot thành 1.1.2 để nhận phiên bản Spring cũ hơn 4.0.6.
Sau đó, em.save (người) hoạt động như mong đợi và Giao dịch hoạt động tốt (nghĩa là khôi phục tất cả chèn db khi RuntimeException xảy ra).
Nhưng ngay cả với mùa xuân 4.0.5 + mùa xuân dữ liệu JPA 1.6.0 phiên bản giao dịch không hoạt động khi personRepository.save (người) được sử dụng thay vì em.persist (người).
Dường như kho lưu trữ dữ liệu Spring JPA đang thực hiện giao dịch.
Tôi đang thiếu gì? Cách đặt các chú thích dịch vụ @Transactional hoạt động?
PS:
Maven pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sivalabs</groupId>
<artifactId>springboot-data-jpa</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-data-jpa</name>
<description>Spring Boot Hello World</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.0.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>com.sivalabs.springboot.Application</start-class>
<java.version>1.7</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>
Application.java
Đăng lớp ứng dụng của bạn và pom maven. Phiên bản Spring Boot bạn đang sử dụng nên sử dụng Spring 4.1.x và không phải cái gì cũ, nếu có một phiên bản khác trong đó bạn có thể có một số phụ thuộc lạ trong danh sách của bạn. –
Đã thêm pom.xml và Application.java –
Đặt 'PersonService'' public' của bạn cũng như phương thức bạn đang gọi. –