1

我必须看到它的底部。这是一个简短的摘要:我有一个Configuration模型对象,它具有一些配置设置以及用户名和密码。当然,密码是加密的,我必须解密才能使用它。务实地,我Configuration用 Hibernate 加载对象(密码是加密的),我得到密码,我解密它,并将密码属性设置为新评估的明文(我使用 setter 方法)。请注意,我再也不会存储该Configuration对象。奇怪的结果是我发现CONFIGURATIONS在数据库中使用密码明文更新了表!我猜 Hibernate 缓存系统在其中扮演了一个神秘的角色,但我必须明白为什么以及如何

详情如下:

我使用的是 Spring 框架,版本 3.1.2 RELEASE

servlet.xml

    <!-- HIBERNATE -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.0.0.Final</version>
    </dependency>

服务

@Service("configurationManager")
public class ConfigurationManager {

    //attributes and blah blah

    public Configuration loadConfiguration()
    {
        //the Configuration's password attribute is encrypted in the db
        Configuration configuration = configurationDao.load();
        if(configuration!=null)
        {
            //...to use the password I must decrypt it
            if(!(configuration.getPassword()==null || configuration.getPassword().isEmpty()))
            {                   
                String encryptedText = configuration.getPassword();
                String decryptedText = credentialsManager.decrypt(encryptedText);
                //after decrypting the password, I set the Configuration's password attribute to the plaintext password
                //I'll never ever store the Configuration obj with the newly set password.
                configuration.setPassword(decryptedText);
            }
        }
        return configuration;
    }   
}

(也许没用)线索:自从我开始将 AOP 用于不同目的时,我注意到了这种 Hibernate 行为。我看不出这两件事之间有明确的联系,但我还是报告了。我在项目中包含了这些库:

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.7.2</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.7.2</version>
    </dependency>   
4

1 回答 1

2

当您使用休眠加载一个对象时,该实例将绑定到您加载它的会话,并跟踪对它的所有更改。当会话最终被刷新(调用适当的方法或在内部由于会话行为上的 FlushMode 选择)时,更改将同步到数据库。

要么不要更改您加载的对象并将未加密的密码存储在例如非持久属性中,要么调用evict将其从会话中分离。

编辑:有关一些背景信息,请参阅休眠文档,特别是第 11.1 节 - 休眠对象状态 - 您可以在那里看到从会话加载的对象处于持久状态,并且当工作单元完成时更改将保持不变(即会话被刷新。

于 2013-05-15T07:23:43.747 回答