如何使用junit,spring和JPA测试乐观锁定?

时间:2015-01-08 13:15:57

标签: spring jpa junit

我的实体有@version列,daos和junit测试。 如何在junit测试用例中引发乐观锁异常,看看它是否正确处理?

我正在使用spring transaction managamemnt,所以这让我觉得更复杂

2 个答案:

答案 0 :(得分:2)

  1. 从jUnit测试方法打开一个事务,并从某个表中读取一行。
  2. 创建一个新线程并打开另一个将读取同一行的数据库事务。
  3. 更新它,并将其保存到数据库中。
  4. 暂停jUnit测试方法使用的主线程。
  5. 修改开头读取的数据并尝试更新该行。因此,应该抛出乐观的锁定异常。

答案 1 :(得分:0)

在我当前的Project中,我们必须处理OptimisticLockException并将其包装到coustomized异常中。而不是Spring,我们正在使用hibernate。但也许这种方式可以帮助你。

对于我的解决方案,您需要在测试中使用OpenEJB-Container:

@LocalClient
public class ExampleClassTest {

    //its a self written class to bootstrap the open ejb container
    private static OpenEjbContainerStarter openEjbStarter;

    private static Context context;

    @Resource
    private UserTransaction userTransaction;

    @EJB
    private ExampleWithSaveActionFacade facade;

    @EJB
    private ExampleDAO exampleDataAccessObject;

    @BeforeClass
    public static void setUpBefore() throws Exception {
        openEjbStarter = new OpenEjbContainerStarter();
        context = openEjbStarter.startOpenEJB();
    }

    @AfterClass
    public static void shutdown() throws NamingException, SQLException {
        openEjbStarter.destroyOpenEJB();
    }

    @Before
    public void before() throws Exception {
        context.bind("inject", this);
    }

    @Test(expected = OptimisticLockException.class)
    public void testSaveSomethingWithException(){

        //get the first object you will manipulate and change the Version
        //current Version is 1
        ExampleModel example = exampleDataAccessObject.findById(1L);
        example.setSomeData("test");

        //get the second object what will cause the exception
        //current version is 1
        ExampleModel exampleOldObject = exampleDataAccessObject.findById(1L);

        // returnValue with the version number 2
        ExampleModel returnValue = facade.persistOrUpdateUser(example);

        //try to save the object with the version 1
        //throws the OptimisticLockException
        facade.persistOrUpdateUser(exampleOldObject);
    }
}