Reputation: 135
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();
}
}
Upvotes: 0
Views: 661
Reputation: 44952
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.
Upvotes: 1