I try to test my @Repository layer using jUnit and integration testing. In my entity classes I use @ManyToMany bidirectional annotation. My test class I have annotated with @Transactional. When I executing persist method on the parent side of relationship the User object and Role are inserted to databse but there is no relations in join table. When I move @Transactional annotation to @Repository class everything works ok. Maybe someone can exaplain me what is the reason why it is no working when @Transactional annotation is on test class?
User entity:
@Table(name = "users")
@Entity
public class User extends BaseEntity {
...
@ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
@JoinTable(
name = "users_roles",
joinColumns = { @JoinColumn(name = "user_id") },
inverseJoinColumns = { @JoinColumn(name = "role_id") }
)
private Set<Role> roles;
.. getters and setters
public void addRole(Role role) {
this.getRoles().add(role);
role.getUsers().add(this);
}
public Set<Role> getRoles() {
if (this.roles == null) {
this.roles = new HashSet<>();
}
return this.roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
Role entity
@Table(name = "roles")
@Entity
public class Role extends BaseEntity {
public enum UserRole {
ADMIN, USER
}
@Enumerated(EnumType.STRING)
@Column(name="role")
private UserRole role;
@ManyToMany(mappedBy = "roles", fetch = FetchType.EAGER,cascade = CascadeType.ALL)
private Set<User> users;
... getters and setters
}
Test class:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MysqlPersistanceConfig.class})
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Transactional
public class UserRepositoryIT {
@Autowired
private UserRepository userRepository;
@Test
public void stage10_saveOneUserAndCheckIfWasSavedTest() {
User user = new User();
user.setName("admin");
user.setPassword("root");
Role role1 = new Role(UserRole.USER);
Role role2 = new Role(UserRole.ADMIN);
user.addRole(role1);
user.addRole(role2);
Assert.assertTrue(role1.getUsers().size() == 1);
Assert.assertTrue(role2.getUsers().size() == 1);
Assert.assertTrue(user.getRoles().size() == 2);
userRepository.save(user);
Assert.assertEquals(user, userRepository.find(1));
Assert.assertEquals(user, userRepository.findByName("admin"));
Assert.assertEquals(2, userRepository.findByName("admin").getRoles().size());
}
}
DAO layer:
@Repository
//@Transactional
public class UserRepositoryImpl implements UserRepository {
@PersistenceContext
private EntityManager manager;
@Override
public void save(User user) {
if(user.isNew()) {
manager.persist(user);
} else {
manager.merge(user);
}
}
@Override
public User find(int id) {
return manager.find(User.class, id);
}
@Override
public User findByName(String name) {
String queryString = "SELECT u FROM User u WHERE u.name = :name";
Query query = manager.createQuery(queryString);
query.setParameter("name", name);
return (User) query.getSingleResult();
}
}
Spring's JUnit is rolling back the transaction spanning the test method by default. If you want to check it use EntityManager manager
in the test and call manager.flush()
or add @Rollback(false)
to test method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.