【发布时间】:2020-06-02 17:27:12
【问题描述】:
我想知道 @Transactional 如何在测试方法上与 Spring Data JPA / Hibernate 一起使用。我在网上搜索了一些解释,但似乎仍然晦涩难懂。
下面是我正在使用的代码:
会员.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...
}
角色.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已创建但为空(无条目):n:n@ManyToMany 单向关系未保存。 - 使用
@Commit时,一切正常:有 2 个条目对应于 John Doe 用户的角色。
这是我的问题:
CrudRepository.save(...) 如何使用 @Transactional 在幕后工作,为什么单独使用这个注解会“部分保存”?我们应该预期,如果没有@Commit,则不会向数据库提交任何内容(并且所有内容都会回滚)。
在测试方法上使用@Transactional 是一种好习惯吗?
【问题讨论】:
-
我从来没有在测试方法上使用过Transaction,一直以来,我在Service类Test类中以正常方式使用它来初始化数据,执行测试,并回滚数据更改给原始测试数据集,确保在每个测试用例运行后都不会修改数据。使下一个测试用例不受前一个测试用例的影响,并且每次测试都会以相同的结果运行。
标签: hibernate jpa junit transactions jta