简体   繁体   English

Hibernate ManyToMany和事务注释

[英]Hibernate ManyToMany and Transactional annotation

I try to test my @Repository layer using jUnit and integration testing. 我尝试使用jUnit和集成测试来测试我的@Repository层。 In my entity classes I use @ManyToMany bidirectional annotation. 在我的实体类中,我使用@ManyToMany双向注释。 My test class I have annotated with @Transactional. 我用@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. 当我在关系的父级上执行persist方法时,会将用户对象和角色插入到数据库中,但联接表中没有关系。 When I move @Transactional annotation to @Repository class everything works ok. 当我将@Transactional注释移到@Repository类时,一切正常。 Maybe someone can exaplain me what is the reason why it is no working when @Transactional annotation is on test class? 也许有人可以替我解释@Transactional注释在测试类上不起作用的原因是什么?

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: DAO层:

@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. Spring的JUnit默认情况下回滚跨越测试方法的事务。 If you want to check it use EntityManager manager in the test and call manager.flush() or add @Rollback(false) to test method. 如果要检查它,请在测试中使用EntityManager manager ,然后调用manager.flush()或将@Rollback(false)添加到测试方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 覆盖事务性注释Spring + Hibernate - Overriding transactional Annotation Spring + hibernate 使用休眠注释映射@ManyToMany关系 - Mapping @ManyToMany relationship with hibernate annotation 对hibernate应用程序使用@Transactional注释会导致错误 - Using @Transactional annotation for hibernate application resulting in error @Transactional注释Spring Boot 2.0和休眠LazyInitializationException - @Transactional annotation Spring boot 2.0 and hibernate LazyInitializationException @ManyToMany Hibernate批注中正确的CascadeType是什么? - What is the correct CascadeType in @ManyToMany Hibernate annotation? 使用HIbernate和Spring的@Transactional批注不能持久保存数据 - Data does not persist using HIbernate with Spring's @Transactional Annotation 事务注解不能解决 org.hibernate.LazyInitializationException - Transactional annotation doesn't solve org.hibernate.LazyInitializationException 对JPA + Hibernate + @Transactional注释的Spring事务支持的奇怪befaviour - Strange befaviour of spring transaction support for JPA + Hibernate +@Transactional annotation Spring / Hibernate项目@Transactional批注值未使用并自动替换 - Spring/Hibernate project @Transactional annotation value is not used and substituted automatically 带有 readOnly 的 Spring Transactional 注释不适用(+Hibernate) - Spring Transactional annotation with readOnly don't apply (+Hibernate)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM