如何可靠地在单元测试中单元测试JPA实体的更新 [英] How can I reliably unit test updates of a JPA entity in a unit test

查看:131
本文介绍了如何可靠地在单元测试中单元测试JPA实体的更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个测试设置,我使用的是spring,derby和JPA,我想测试更新是否正常。

我无法真正做到这一点标准的方式,也就是说。创建一个实体对象,坚持,再次找到对象,改变对象中的某个字段,再次坚持,做一个查找,看它是否已经改变。



方法是我没有得到实体的新实例。它总是一样的。所以我无法确定更新是否正常工作,因为我总是更改同一个对象,所以任何更改都会过早地反映出来。



如果我更改某个对象没有将它与persistencecontext合并,然后尝试对该对象进行查找,该查找中已经存在该更改,因为它始终与同一对象一起工作。



有什么办法可以丢失上下文,并做一个真正的测试,更新是否正常工作?



这是我目前的代码:

  @Test 
public void canUpdate(){

JsonTestEntity entity1 = new JsonTestEntity();
JsonTestEntity entity2 = new JsonTestEntity();

String message =OmegaCV1;
字符串message2 =OmegaCV2;

entity1.setMessage(message);
entity2.setMessage(message2);

em.persist(entity1);
em.persist(entity2);

em.flush();

JsonTestEntity jsonTestEntity = em.find(JsonTestEntity.class,entity2.getId());

assertNotNull(Could not find persisted entity,jsonTestEntity);
assertEquals(不是同一个实体,message2,jsonTestEntity.getMessage());

字符串changeMes​​sage =更改消息;
jsonTestEntity.setMessage(changeMes​​sage);

JsonTestEntity unChangedEntity = em.find(JsonTestEntity.class,entity2.getId());

assertEquals(Message was earlyly changed,message2,unChangedEntity.getMessage());
em.merge(jsonTestEntity);

JsonTestEntity changedEntity = em.find(JsonTestEntity.class,entity2.getId());
assertEquals(Message was not changed,changeMes​​sage,changedEntity.getMessage());


解决方案

禁用EntityManager的第一级缓存 - 它可以解决你的问题:)

所以我有几点想法:


  1. 如果您的EntityManager是每个事务 - 只要执行 persist() find() em.clear() - 它会分离所有的交易。

  2. 管理实体。不要忘记在 em.flush()之前提交更改。 如果你使用Hibernate - 在 persist()。flush()之前清除Session:

    Session session = em。解开(Session.class);
    session.flush();
    session.clear();

  3. 您也可以使用 Session.refresh()重新加载实体的状态c $ c


    文档:


    I have this test setup where I'm using spring, derby and JPA and I want to test whether updates work.

    I can't really do this in the standard way, that is. Create an entity object, persist, find object again, change some field in the object, persist again, do a find to see whether it has changed.

    The problem with that approach is that I don't get a new instance of the entity. It is always the same. So I can't really tell if update works correctly because I am always changing the same object, so any change is reflected prematurely.

    If I make a change to some object without merging it with the persistencecontext, and then try to do a find on that object, the change is already present in the find as it is always working with the same object.

    Is there any way I can lose the context and do a real test that updating is working correctly?

    Here is my current code:

    @Test
    public void canUpdate() {
    
        JsonTestEntity entity1 = new JsonTestEntity();
        JsonTestEntity entity2 = new JsonTestEntity();
    
        String message = "OmegaCV1";
        String message2 = "OmegaCV2";
    
        entity1.setMessage(message);
        entity2.setMessage(message2);
    
        em.persist(entity1);
        em.persist(entity2);
    
        em.flush();
    
        JsonTestEntity jsonTestEntity = em.find(JsonTestEntity.class, entity2.getId());
    
        assertNotNull("Could not find persisted entity", jsonTestEntity);
        assertEquals("Was not same entity", message2, jsonTestEntity.getMessage());
    
        String changeMessage = "Changed message";
        jsonTestEntity.setMessage(changeMessage);
    
        JsonTestEntity unChangedEntity = em.find(JsonTestEntity.class, entity2.getId());
    
        assertEquals("Message was prematurely changed", message2, unChangedEntity.getMessage());
        em.merge(jsonTestEntity);
    
        JsonTestEntity changedEntity = em.find(JsonTestEntity.class, entity2.getId());
        assertEquals("Message was not changed", changeMessage, changedEntity.getMessage());
    }
    

    解决方案

    If there was a possibility to disable EntityManager's 1st level cache - it would solve your problem :)

    So I have a few ideas :

    1. If your EntityManager is per-transaction - just do the persist() and find() in different transactions.

    2. Use em.clear() - it will detach all managed entities. Don't forget to em.flush() before this to commit the changes.

    3. If you use Hibernate - clear the Session after persist().flush() it before :

      Session session = em.unwrap(Session.class); session.flush(); session.clear();

    4. Also you can reload the entity's state using Session.refresh()

    Docs :

    这篇关于如何可靠地在单元测试中单元测试JPA实体的更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆