Hibernate:如何禁用自动保存脏对象?

mac*_*ery 22 hibernate transactions

我很惊讶地发现Hibernate会在事务结束时自动保存脏对象,而不会显式调用类似的东西

dao.save(object)
Run Code Online (Sandbox Code Playgroud)

我想到了这个线程所描述的情况

我的问题是:有没有办法禁用这种行为?乍一看,这种自动保存看起来相当危险,因为您需要知道哪些对象连接到会话,哪些不是,并且似乎很容易错误地保存.你能告诉我这种自动保存方法的好处是什么?我什么都看不到.我想总是显式调用dao.save(object)来更新任何东西.

我听说过一个可能的解决方法,就是在sessionFactory上使用entityInterceptor.这个自定义entityInterceptor会覆盖findDirty方法,永远不会找到任何脏东西,但在这种情况下,我认为dao.save也不会起作用.有任何想法吗?

Gré*_*ory 12

我同意,你不应该手动冲洗.我对webapp开发人员的经验说FushMode应该设置为"AUTO".但有时我需要禁用脏检查(用于验证数据,验证数据库中的数据以及通过表单或服务返回数据).为此,我通过更改FLUSHMODE创建一个特殊类并禁用脏检查

@Component
public class ValidateRefPaysService implements IValidateRefPaysService {

    ...

    @Autowired
    @Qualifier("sessionFactory")
    private SessionFactory sessionFactory;

    @Override
    @Transactional(readOnly=true) 
    public void validate(RefPays refPays) throws BusinessException {

        try {
            sessionFactory.getCurrentSession().setFlushMode(FlushMode.MANUAL);

            if ( refPays.getId() != null ) {
                RefPays refPaysBase = refPaysDAO.getById(refPays.getId());
                if ( refPaysBase != null )  {
                    throw new BusinessException("L'id already exists in database.", "RefPays.savePays.id.alreadyexist", "refPays.savePays.id.alreadyexist");
                }
            }
        } finally {
            sessionFactory.getCurrentSession().setFlushMode(FlushMode.AUTO);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*erl 5

要禁用自动状态管理,请将会话上的刷新模式设置为手动。然后,您可以调用 session.flush() 来实际写出与会话关联的所有脏实体。

  • @StefanHaberl 这是主要优点之一吗?您多久编写一次代码而不对您真正想要保存的实体明确发出“保存”?Ofc 脏检查应该仍然存在,因此如果您发出保存并且实体不脏,则不会向数据库发出查询。 (11认同)
  • 嗯...我真的不想禁用 Hibernate 自动刷新 - 这会导致我失去 Hibernate 与性能相关的设施的好处。我只希望那些我明确调用 dao.save 或 dao.update 的对象是脏的... (9认同)