我想知道@Transactional在Spring Data JPA/Hibernate测试方法中是如何工作的。我在网上搜索了一些解释,但仍然不太清楚。
以下是我正在使用的代码:
Member.java
@Entity
@Table(name = "MEMBER")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
String firstname;
String lastname;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
name = "MEMBER_ROLE",
joinColumns = @JoinColumn(name = "member_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles = new HashSet<Role>();
// Getters...
// Setters...
}
Role.java
@Entity
@Table(name = "ROLE")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String description;
public Role(String name, String description) {
this.name = name;
this.description = description;
}
@ManyToMany(mappedBy = "roles", cascade = CascadeType.ALL)
private Set<User> users = new HashSet<User>();
public void addUser(User user) {
users.add(user);
user.getRoles().add(this);
}
// Getters...
// Setters...
}
MemberRepositoryTest.java
@SpringBootTest
public class MemberRepositoryTest {
@Autowired
private MemberRepository memberRepository;
@Test
@Transactional
//@Commit // When @Commit is uncommented, the relation is saved in the database
public void testSave() {
Member testMember = new Member();
testMember.setFirstname("John");
testMember.setLastname("Doe");
Role role1 = new Role("ROLE_USER", "The role of for basic users");
Role role2 = new Role("ROLE_ADMIN", "The role of for admin users");
testMember.getRoles().add(role1);
testMember.getRoles().add(role2);
this.memberRepository.save(testMember);
// The 2 roles are well in the set
System.out.println("********" + this.memberRepository.findById(1).get().getRoles().toString());
}
}
- 事情是这样的,当我单独使用 @Transactional 而不使用 @Commit 时,只创建了用户和角色条目。表
MEMBER_ROLE
被创建了但是为空(没有条目):即 @ManyToMany 单向关系未被保存。 - 当使用
@Commit
时,一切正常:与 John Doe 用户角色对应的有两个条目。
以下是我的问题:
CrudRepository.save(...) 在使用 @Transactional 时的内部工作原理是什么?为什么只使用这个注解会导致“部分保存”?我们本应该期望在没有 @Commit
的情况下,不会提交任何内容到数据库中(而是全部回滚)。
在测试方法中使用 @Transactional
是一个好习惯吗?