Hibernate: как отключить автоматическое сохранение грязных объектов?

Я был очень удивлен, узнав, что Hibernate автоматически сохраняет грязные объекты в конце транзакции, без явных вызовов на что-то вроде

dao.save(object)

Я имею в виду ситуацию, описанную > этот поток

Мой вопрос: есть ли способ отключить это поведение? На первый взгляд это автоматическое сохранение кажется довольно опасным, потому что вам нужно знать, какие объекты связаны с сеансом, а какие нет, и кажется довольно легко что-то сэкономить по ошибке. Можете ли вы сказать мне, каковы преимущества этого подхода с автоматическим сбережением? Я почти ничего не вижу. Я хотел бы всегда явно ссылаться на dao.save(object), чтобы что-то обновить.

Я слышал об одном возможном обходном пути к этому, который использует entityInterceptor на вашем sessionFactory. Этот пользовательский объектInterceptor переопределит метод findDirty, чтобы никогда не найти что-либо грязное, но в этом случае я полагаю, что dao.save также не будет работать. Любые идеи?

Ответы

Ответ 1

Я согласен, вы не должны рушить вручную. Мой опыт разработчика 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);
        }
    }
}

Ответ 2

Чтобы отключить автоматическое управление состоянием, установите режим очистки на вашем сеансе в MANUAL. Затем вы можете вызвать session.flush(), чтобы фактически выписать все грязные объекты, связанные с вашим сеансом.