Spring Data jpa如何知道属性已更改?

时间:2014-04-07 21:53:17

标签: java spring-data-jpa

所以说我从存储库中查找一个对象。如果我在查找后立即保存此对象,Spring Data足够聪明,不会更新数据库。如果我更改此对象中的属性然后保存,则spring数据会进行更新。它是如何知道需要更新的?

2 个答案:

答案 0 :(得分:1)

这不是Spring Data提供的,它是你的持久性框架(hibernate,openjpa,eclipselink,...)的一个特性。

持久性提供程序使用一些“东西”来增强域对象以进行优化。通常,这是通过所谓的运行时增强来完成的,因此您的类会在应用程序内部加载并在那里得到增强(运行时编织)。

Openjpa还允许构建时增强,这意味着,“openjpa-domain-extension-stuff”会在编译时添加到您的实体中。 (openjpa插件中也有maven目标) https://openjpa.apache.org/builds/2.2.2/apache-openjpa/docs/ref_guide_pc_enhance.html

如果您运行mvn openjpa:增强您的简单域将如下所示: (我用jad来反编译这个类,因为它是为了显示所有内容,我复制了最相关的部分)

import org.apache.openjpa.enhance.*;
import org.apache.openjpa.util.IntId;
import org.apache.openjpa.util.InternalException;

public class Entity implements PersistenceCapable
{  
    public Integer getId()
    {  
        return pcGetid(this);
    }
    public void setId(Integer id)
    {
        pcSetid(this, id);
    }
    ....
    .... 
    private static final void pcSetid(Entity entity, Integer integer)
    {  
        if(entity.pcStateManager == null)
        {  
            entity.id = integer;
            return;
        } else
        {  
            entity.pcStateManager.settingObjectField(entity, pcInheritedFieldCount + 3, entity.id, integer, 0);
            return;
        }
    }
    ....
    protected void pcClearFields()
    {  
        id = null;
    }

    public PersistenceCapable pcNewInstance(StateManager statemanager, Object obj, boolean flag)
    {  
        Entity entity = new Entity();
        if(flag)
            entity.pcClearFields();
        entity.pcStateManager = statemanager;
        entity.pcCopyKeyFieldsFromObjectId(obj);
        return entity;
    }
} 

通过操纵您的实体,可以调用pcStateManager。如果运行持久性操作,则持久性框架会检查statemanager是否存在实体中的更改,并在必要时将更新发送到数据库。

答案 1 :(得分:0)

Spring实际上并不直接在您的类的实例上工作。它的作用是创建一个包装实际实例并委托给它的代理。此代理保存基础实例的持久性状态。换句话说,它知道实例是否处于与数据库中相同的状态,就像它在内存中一样。

如果你调用(某些)方法,它会认为自己很脏。 EntityManager必须推动这些更改。如果不这样做,那么它也知道不需要推送任何更改。