在测试和控制器中标记事务的方法的不同行为

时间:2013-09-24 09:31:58

标签: java spring hibernate transactions

我将CandidateService类标记为@Transactional

@Transactional
@Service("candidateService")
public class CandidateService {

    @Autowired
    private CandidateDao candidateDao;

    ....

    public void add(Candidate candidate) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        String login = auth.getName();
        User user =  utilService.getOrSaveUser(login);
        candidate.setAuthor(user);
        candidateDao.add(candidate);
    }
   ...
}

dao实现:

@Override
    public Integer add(Candidate candidate) throws HibernateException{
        Session session = sessionFactory.getCurrentSession();
        if (candidate == null) {
            return null;
        }
        Integer id = (Integer) session.save(candidate);
        return id;

    }

如果我写在@controller类:

@RequestMapping("/submitFormAdd")
    public ModelAndView submitFormAdd(
            Model model,
            @ModelAttribute("myCandidate") @Valid Candidate myCandidate,
            BindingResult result,
            RedirectAttributes redirectAttributes) {
        if (result.hasErrors()) {
            return new ModelAndView("candidateDetailsAdd");
        }

        myCandidate.setDate(new Date());
        candidateService.add(myCandidate);

    .....
    }

执行此方法数据后,将数据放入数据库!

如果我写测试:

@ContextConfiguration(locations = {"classpath:/test/BeanConfig.xml"})
public class CandidateServiceTest extends AbstractTransactionalJUnit4SpringContextTests{

    @Autowired
    CandidateService candidateService;

    @BeforeClass
    public static void initialize() throws Exception{

        UtilMethods.createTestDb();

    }
    @Before
    public void setup() {
        TestingAuthenticationToken testToken = new TestingAuthenticationToken("testUser", "");
        SecurityContextHolder.getContext().setAuthentication(testToken);
    }

    @After
    public void cleanUp() {
        SecurityContextHolder.clearContext();
    }
    @Test
    public void add(){
        Candidate candidate = new Candidate();
        candidate.setName("testUser");
        candidate.setPhone("88888");
        candidateService.add(candidate);
        List<Candidate> candidates = candidateService.findByName(candidate.getName());
        Assert.assertNotNull(candidates);
        Assert.assertEquals("88888", candidates.get(0).getPhone());
    }
}

测试为绿色,但执行后我没有在数据库中看到数据。

你能解释一下为什么以及如何解决它?

更新

configuration:
<tx:annotation-driven transaction-manager="transactionManager" />

    <!-- Менеджер транзакций -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

3 个答案:

答案 0 :(得分:1)

@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
测试类上方的

不会影响数据库。

设置或添加defaultRollback = false以查看表中保留的数据。

答案 1 :(得分:0)

我认为您应该使用param defaultRollback = false

添加TransactionConfiguration批注

答案 2 :(得分:0)

完成测试方法后,将回滚更改。恢复测试方法数据库更改,您可以使用新数据执行其他测试。 在不同的测试用例中,您无需担心具有相同ID的模型对象。

如果您需要通用数据,则可以在setup()方法中执行更改,这些更改也未保存在数据库中。

在执行测试方法之前,将调用setup()方法。如果你有3个测试方法,那么将调用3次setup()方法。

抱歉我的英语不好.......