Hibernate ManyToMany and Transactional annotation

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")
public class User extends BaseEntity  {


    @ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
        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) {

    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")
public class Role extends BaseEntity {

    public enum UserRole {
        ADMIN, USER

    private UserRole role;

    @ManyToMany(mappedBy = "roles", fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    private Set<User> users;

    ... getters and setters

Test class:

@ContextConfiguration(classes = {MysqlPersistanceConfig.class})
public class UserRepositoryIT {

    private UserRepository userRepository;

    public void stage10_saveOneUserAndCheckIfWasSavedTest() {
        User user = new User();

        Role role1 = new Role(UserRole.USER);
        Role role2 = new Role(UserRole.ADMIN);


        Assert.assertTrue(role1.getUsers().size() == 1);
        Assert.assertTrue(role2.getUsers().size() == 1);
        Assert.assertTrue(user.getRoles().size() == 2);


        Assert.assertEquals(user, userRepository.find(1));
        Assert.assertEquals(user, userRepository.findByName("admin"));
        Assert.assertEquals(2, userRepository.findByName("admin").getRoles().size());

DAO layer:

public class UserRepositoryImpl implements UserRepository {

    private EntityManager manager;

    public void save(User user) {
        if(user.isNew()) {
        } else {

    public User find(int id) {
        return manager.find(User.class, id);

    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();

1 answer

  • answered 2018-03-13 20:40 Karol Dowbecki

    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.