Java Spring数据jpa如何知道属性已更改?

Java Spring数据jpa如何知道属性已更改?,java,spring-data-jpa,Java,Spring Data Jpa,假设我从存储库中查找一个对象。如果我在查找后立即保存此对象,则Spring数据足够智能,不会更新数据库。如果我在这个对象中更改了一个属性,然后保存,spring数据会进行更新。它如何知道它是否需要进行更新?Spring实际上并不直接在类的实例上工作。它所做的是创建一个代理来包装实际实例并委托给它。此代理保存基础实例的持久性状态。换句话说,它知道实例在数据库中的状态是否与在内存中的状态相同 如果调用(某些)方法,它会认为自己是脏的。EntityManager必须推动这些更改。如果您不这样做,那么它

假设我从存储库中查找一个对象。如果我在查找后立即保存此对象,则Spring数据足够智能,不会更新数据库。如果我在这个对象中更改了一个属性,然后保存,spring数据会进行更新。它如何知道它是否需要进行更新?

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


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

这不是Spring数据提供的,它是您的持久性框架(hibernate、openjpa、eclipselink等)的一个特性

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

Openjpa还允许构建时增强,这意味着“Openjpa域扩展”将在编译时添加到实体中。(openjpa插件中也有一个maven目标)

如果您运行mvn openjpa:enhance,您的简单域将如下所示: (我使用jad对类进行反编译,因为要显示其中的所有内容太长了,所以我复制了最相关的部分)


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

尝试执行
yourObject.getClass()
。那会有什么回报?
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;
    }
}