powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate - cохранение объекта
37 сообщений из 37, показаны все 2 страниц
Hibernate - cохранение объекта
    #39301216
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БД - Oracle, создан сиквенс и привязан аннотацией к объекту. При создании нового java-объекта поле id изначально равно нулю. Когда объект сохраняется через save(obj) метод отрабатывает успешно и генерируется id отличный от нуля, хотя одно из полей в таблице (назовем его условно field) имеет уникальный индекс. Затем происходит выход из транзакции (из метода, помеченного аннотацией @Transactional). В этот момент выбрасывается исключение нарушения ограничения уникальности field, транзакция откатывается. Сгенерированный id остается в java-объекте, что неприятно, приходится "вручную" его обнулять.

Вопрос. Почему исключение не возникло на самом save(obj)? То есть хибер закэшировал вставку?! Ведь если зайти в pl/sql developer и вручную провести подобную операцию, то исключение появится сразу, а не при попытке зафиксировать транзакцию.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301220
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaПри создании нового java-объекта поле id изначально равно нулю.
Почему не null?

myauchaСгенерированный id остается в java-объекте, что неприятно, приходится "вручную" его обнулять.

А вот это интересный факт.

myauchaВопрос. Почему исключение не возникло на самом save(obj)?
Потому что Session aka EntityManager aka Unit of Work ещё называется кешем первого уровня. Это такая оптимизация, чтобы на каждый пук не генерировать SQL запрос. Для особо торопливых есть метод flush()

myauchaТо есть хибер закэшировал вставку?!

Конечно.

myauchaВедь если зайти в pl/sql developer и вручную провести подобную операцию, то исключение появится сразу, а не при попытке зафиксировать транзакцию.
Ведь ORM и PL/SQL это не одно и то же?
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301224
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myaucha,

По поводу отката id вот тут хорошо описано
http://stackoverflow.com/questions/20636144/entity-state-and-entity-id-value-in-jpa-hibernate-after-rollback
JPA требует такого поведения
Но хибер позволяет включить опцию hibernate.use_identifier_rollback
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301323
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока читаю про состояния объекта попутно задам уточняющие вопросы

BlazkowiczmyauchaПри создании нового java-объекта поле id изначально равно нулю.
Почему не null?Объявлял id как int, поэтому и ноль. Есть какие-то предубеждения против использования простых типов в качестве идентификаторов?!

BlazkowiczПо поводу отката id вот тут хорошо описано
http://stackoverflow.com/questions/20636144/entity-state-and-entity-id-value-in-jpa-hibernate-after-rollback
JPA требует такого поведения
Но хибер позволяет включить опцию hibernate.use_identifier_rollbackОпция use_identifier_rollback не помогла. Добавлял ее, как в таком варианте - hibernate.use_identifier_rollback, так и без префикса - use_identifier_rollback.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301334
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaЕсть какие-то предубеждения против использования простых типов в качестве идентификаторов?!
Конечно. БД разрешает вам хранить 0 в колонке первичного ключа. А вот null не разрешит.

myauchaв таком варианте - hibernate.use_identifier_rollback, так и без префикса - use_identifier_rollback.
Тут я ничего не могу сказать. Надо посмотреть как он используется в исходнике. И куда вы его вообще пихали.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301347
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczmyauchaЕсть какие-то предубеждения против использования простых типов в качестве идентификаторов?!
Конечно. БД разрешает вам хранить 0 в колонке первичного ключа. А вот null не разрешит.Пока не убедили. Если приложение выполняет проверку на id == 0 и отправляет объект в зависимости от результата либо на save(obj), либо на update(obj), то риска вроде бы нет?!

myauchaв таком варианте - hibernate.use_identifier_rollback, так и без префикса - use_identifier_rollback.
Тут я ничего не могу сказать. Надо посмотреть как он используется в исходнике. И куда вы его вообще пихали.[/quot]В статье (да и в документации к настройке это прописано) высказывались предположения о том, что эта настройка работает только для delete.

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.use_identifier_rollback">true</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>



Вы-то сами как поступаете в проектах с идентификаторами объектов, когда выполняется Вставка и нарушаются ограничения, приводящие к откату?
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301361
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaто риска вроде бы нет?!
Assumption is the mother of all fuck ups.
1) Целостность данных БД нужно обеспечивать средствами БД, а не ORM.
2) Сторонние библиотеки (например Spring Data) не в курсе деталей вашего Hibernate маппинга и опираются на общие практики, такие как проверку id на null.
3) В случае присвоения кем-то значения 0 по ошибке (генератор сломался или ещё какой лисопед самоуправством занялся) вы не сможете отличить его от значения 0 по-умолчанию.
4) Некоторые бд имеют по-умолчанию инкремент от 0. Что может выйти боком, когда вдруг понадобится портировать с Oracle.

Остаётся вопрос. Почему бы сразу не убрать грабли?


myauchaВы-то сами как поступаете в проектах с идентификаторами объектов, когда выполняется Вставка и нарушаются ограничения, приводящие к откату?
Обычно, я про этот объект забываю. Он невалидный. Зачем мне его состояние? Нужно сформировать новый.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301393
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaВы-то сами как поступаете в проектах с идентификаторами объектов, когда выполняется Вставка и нарушаются ограничения, приводящие к откату?Обычно, я про этот объект забываю. Он невалидный. Зачем мне его состояние? Нужно сформировать новый.[/quot]Вколачивал пользователь данные в форму, они пришли в контроллер в виде объекта, объект семантически верный, пытаемся его сохранить, но ограничения в БД не позволили это сделать. Логично передать объект пользователю обратно на доработку.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301402
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaВколачивал пользователь данные в форму, они пришли в контроллер в виде объекта, объект семантически верный, пытаемся его сохранить, но ограничения в БД не позволили это сделать. Логично передать объект пользователю обратно на доработку.
Во-первых, объекты на UI и в ORM совпадают только в простейших случаях. При большой модели предметной области оказывается очевидным что объекты на UI нужны совсем не такие как в ORM.
Во-вторых почему мы в UI потеряли данные, если мы их ещё не сохранили?
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301432
no56892
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myaucha,
1.Руками обнулять.
2.Первой же строчкой в сервисе делать копию того, что пришло.
3.Dto и им подобное.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301435
no56892
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПри большой модели предметной области оказывается очевидным что объекты на UI нужны совсем не такие как в ORM.
Вопрос нахрена тогда вообще нужен ORM?
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301443
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myaucha,
Значит на sql.ru дураки. Т.к. в форуме если объект не прошел, то он потерян.
Хотя написать за свой счет можно что угодно. Заказчик только рад будет.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301447
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczВо-первых, объекты на UI и в ORM совпадают только в простейших случаях. При большой модели предметной области оказывается очевидным что объекты на UI нужны совсем не такие как в ORM.
Во-вторых почему мы в UI потеряли данные, если мы их ещё не сохранили?В общем понятно. В простом случае (когда объект ввода является объектом сохранения) тот объект, который приходит в контроллер надо копировать и сохранять в базу уже копию. Если транзакция завершается откатом, то копию забываем и передаем пользователю для повторного редактирования оригинал.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301449
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myaucha,
Разве при райзе у вас объект куда то пропал?
1. Правило в веб - не допускать райзе. Откуда оно?
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301477
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no56892Вопрос нахрена тогда вообще нужен ORM?
Ну, если у вас кроме UI и БД других слоёв нет, то в вашей архитектуре, вероятно не нужен.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39301478
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaВ общем понятно. В простом случае (когда объект ввода является объектом сохранения) тот объект, который приходит в контроллер надо копировать и сохранять в базу уже копию. Если транзакция завершается откатом, то копию забываем и передаем пользователю для повторного редактирования оригинал.
Обратите ещё внимание на такую фичу hibernate как dirty check. Описанный вами вариант не единственный. Например можно контроллер научить заполнять уже загруженный объект. А не использовать тот, который он создал.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302223
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще один вопрос. Поскольку он связан с существующим, то не буду создавать отдельную тему. Если происходит сохранение объекта в методе контроллера через вызов service.save(obj). Метод используется для создания нового объекта или изменения существующего. Известно, что при сохранении могут возникнуть две ошибки, которые должны быть обработаны. Первая ошибка ObjAlreadyExists возникает когда объект с указанным именем уже существует в базе, вторая ObjNotFound - объект не найден в базе (например, в результате оптимистичного метода редактирования и последующего сохранения). Естественно возникает желание сделать нечто такое:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
            try {
                obj = service.save(obj);
            }
            catch (ObjAlreadyExists e) {
                bindingResult.rejectValue("obj", "NotUnique.obj.name");
                return InitObjEditModel(obj, "edit");
            }
            catch (ObjNotFound e) {
                bindingResult.rejectValue("obj", "NotFound.obj.id");
                return InitObjEditModel(obj, "edit");
            }



В самом service.save вызывается dao.save, в нем генерируются исключения, но не ObjAlreadyExists или ObjNotFound, а другие унаследованные от DataAccessException или от RuntimeException. Причем, реализация dao может быть выполнена для jdbc, для hibernate или для чего-то еще. В каждой реализации исключения будут разные (некоторые могут и совпадать). Есть желание трансформировать их в ObjAlreadyExists и ObjNotFound. В документации Spring указано, что потомки DataAccessException - это преобразованные (например, из jdbc или hibernate исключений) runtime-исключения, и что Spring рекомендует использовать именно их вместо нудных описаний throws в методах. Предположим, их доводы убедительны плюс не хочется засорять код dao-реализаций конструкциями try/catch и генерированием соответствующих ObjAlreadyExists и ObjNotFound-исключений. Поэтому объявляю ObjAlreadyExists и ObjNotFound наследниками runtime-исключений и пытаюсь их преобразовать...

Вопрос где лучше сделать такое преобразование?! Если сделать отдельный метод в контроллере, обозначив его аннотацией @ExceptionHandler, то после преобразования уже, насколько я понимаю, не получится вернуться в try/catch obj = service.save(obj) и продолжить оперировать объектами obj или bindingResult. То есть, существует ли способ перехватить исключение, выполнить преобразование и продолжить подниматься по цепочке вызовов. Насколько я понял, разные варианты реализации обработки - @ControllerAdvice или интерфейс HandlerExceptionResolver - это все обработка упущенных (необработанных) исключений. А нужен некий interceptor.

Может вообще надо делать по-старинке (по крайней мере для данного примера) - в dao перехватывать исключения и генерировать ObjAlreadyExists и ObjNotFound, унаследованные от обычного Exception. И протянуть (посредством throws-описания в заголовке метода) их через dao.save и service.save, обязав к тому же пользователя предусмотреть обработку try/catch?!
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302243
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaЕще один вопрос. Поскольку он связан с существующим, то не буду создавать отдельную тему.
В подфоруме Java все вопросы связаны одной технологией. Ваш новый вопрос к первоначальному ведь не относится совершенно.

myauchaПервая ошибка ObjAlreadyExists возникает когда объект с указанным именем уже существует в базе
У объектов нет имён. И кстати, в случае ORM говорят о сущностях (entity), потому как два объекта могут быть одной сущностью, например.

myauchaвторая ObjNotFound - объект не найден в базе (например, в результате оптимистичного метода редактирования и последующего сохранения).
Вот этого я вообще не понял. Как NotFound связан с оптимистичной блокировкой?

myauchaВ самом service.save вызывается dao.save, в нем генерируются исключения, но не ObjAlreadyExists или ObjNotFound

DAO для ORM почти бесполезны. Обычно они вырождаются в Repository.

myaucha, а другие унаследованные от DataAccessException или от RuntimeException.
Если вам это критично, то нужно для каждой реализации написать обработчик и конвертор исключений.
http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/dao.html

myauchaПричем, реализация dao может быть выполнена для jdbc, для hibernate или для чего-то еще.
Я надеюсь вы не используете одну и ту же базу для JDBC и ORM?

myauchaВ документации Spring указано, что потомки DataAccessException - это преобразованные (например, из jdbc или hibernate исключений) runtime-исключения, и что Spring рекомендует использовать именно их вместо нудных описаний throws в методах.

Зачем вы всё в кучу мешаете? DataAccessException это одно. Runtime vs Checked Exception это отдельная тема.

myauchaВопрос где лучше сделать такое преобразование?!

Очевидно, что в DAO.

myauchaЕсли сделать отдельный метод в контроллере, обозначив его аннотацией @ExceptionHandler, то после преобразования уже, насколько я понимаю, не получится вернуться в try/catch obj = service.save(obj) и продолжить оперировать объектами obj или bindingResult. То есть, существует ли способ перехватить исключение, выполнить преобразование и продолжить подниматься по цепочке вызовов. Насколько я понял, разные варианты реализации обработки - @ControllerAdvice или интерфейс HandlerExceptionResolver - это все обработка упущенных (необработанных) исключений. А нужен некий interceptor.

Ну, логично что это можно сделать через AOP. Но только не на уровне MVC, когда уже поздно обрабатывать ошибку обращения к данным.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302263
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myaucha,
Где ты взял эти исключения?
У тебя весь роман текста построен на этих двух именах.
Может
SaveOrUpdate (объект
?
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302545
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В итоге получилось следующее

Исключения
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
public final class Exceptions {

    private Exceptions() {}

    public static class UserAlreadyExists extends DuplicateKeyException {
        public UserAlreadyExists(User user, Throwable cause) {
            super("User id [" + user.getUsername() + "] already exists", cause);
        }
    }

    public static class UserNotFound extends DataRetrievalFailureException {
        public UserNotFound(User user, Throwable cause) {
            super("User id [" + user.getId() + "] not found", cause);
        }
    }
}


Контроллер
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
            ...
            try {
                user = userService.save(user);
            }
            // уже существует
            catch (Exceptions.UserAlreadyExists e) {
                bindingResult.rejectValue("username", "NotUnique.user.username");
                return InitUserEditModel(user, error_cmd);
            }
            // не найден (возможно был удален)
            catch (Exceptions.UserNotFound e) {
                bindingResult.rejectValue("username", "NotFound.user.username");
                return InitUserEditModel(user, error_cmd);
            }
            ...


Сервис
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public User save(User user) {

        User copyUser = new User(user);
        userDAO.save(copyUser);
        return copyUser;
    }


DAO (JDBC)
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
    @Override
    public void save(User user) {

        try {
            if (user.getId() == null)
                insert(user);
            else
                update(user);
        }
        catch (DuplicateKeyException e) {
            throw new Exceptions.UserAlreadyExists(user, e);
        }
    }

    private void update(User user) {
        ...
        if (jdbcTemplate.update(SQL, params) == 0)
            throw new Exceptions.UserNotFound(user, null);
    }


DAO (Hibernate)
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
    @Override
    public void save(User user) {

        try {
            getCurrentSession().saveOrUpdate(user);
            getCurrentSession().flush();
        }
        catch(ConstraintViolationException e) {
            throw new Exceptions.UserAlreadyExists(user, e);
        }
        catch(StaleStateException e) {
            throw new Exceptions.UserNotFound(user, e);
        }
    }



Особенности: Поскольку исключения UserAlreadyExists и UserNotFound рантаймовские, то при написании в контроллере userService.save не будет требования их обработки - это минус. Зато не надо тянуть их через слои и прописывать атрибут rollbackFor для @Transactional, чтобы откатывалась транзакция.

Странности: В DAO для jdbc перехватывается ошибка spring-а DuplicateKeyException, то есть уже после преобразования. В DAO же для hibernate перехватываются хибернетовские исключения ConstraintViolationException и StaleStateException. Если выйти из хибернетовского save, то ошибка останется по-прежнему ConstraintViolationException. Если выйти из сервисного save, то исключение преобразуется в spring-овое. Если теперь прописать в настройках
Код: xml
1.
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

, то В DAO для hibernate по-прежнему перехватываются хибернетовские исключения, на выходе они преобразуются в spring-овые, при выходе из транзакции как и раньше - spring-овые. Сейчас, пока писал, понял почему для JDBC сразу получаю spring-овое - потому что через jdbcTemplate работаю. Так что все понятно.

Ну и flush пришлось все-таки написать, потому что иначе ошибку можно будет отловить только на выходе из транзакции (то есть в контролере), а тогда уже поздно - выходить из сервиса ошибка должна уже преобразованной.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302561
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaUserAlreadyExists и UserNotFound
где взял эти исключения?
Их не будет при сохранении объекта хибером.
19618727
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302566
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myaucha,
вот это DuplicateKeyException - с чего вдруг у тебя появится?
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302584
no56892
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myaucha,
У тебя какая-то фигня с настройкой Spring + hibernate походу.
DuplicateKeyException это если только делать persist с уже проставленным id - то возможно.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302588
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no56892myaucha,
У тебя какая-то фигня с настройкой Spring + hibernate походу.
DuplicateKeyException это если только делать persist с уже проставленным id - то возможно.
+1
Что-то он неделю борется как Дон кихот с этой проблемой.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302591
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В хибере (ОРМ) всё просто:
- мы знаем какой (новый или существующий) мы правим и указываем хиберу
- хибер сам знает что делать чтобы исключений не было
- если СПЕЦИАЛЬНО указать ему что не надо затирать изменения соседом, то будет исключение всего одно по оптимистической блокировке.
Всё.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302627
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Основная идея - привести DAO(JDBC) и DAO(Hibernate) к общему знаменателю, чтобы при подмене одного на другой не пришлось ничего меня в сервисе и контроллере. Для этих целей введены два новых исключения, расширяющие стандартные спринговые и более точно характеризующие ошибки.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302653
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaОсновная идея - привести DAO(JDBC) и DAO(Hibernate) к общему знаменателю, чтобы при подмене одного на другой не пришлось ничего меня в сервисе и контроллере. Для этих целей введены два новых исключения, расширяющие стандартные спринговые и более точно характеризующие ошибки.
это у вас программисты сами себе такие задачи могут ставить?
По задаче - "Эх, нету на вас руководителя проекта со сроками").
По сабжу я привёл выше:
У DAO(Хибера) нет ошибок в виде райзе в стандартной многопользовательской работе (веб проект).
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302662
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123У DAO(Хибера) нет ошибок в виде райзе в стандартной многопользовательской работе (веб проект).А теперь переведите эту фразу на русский?
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302676
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myaucha,
может с тебя начнём?
Я спросил, при каком юз кейсе или ВИ у тебя происходит райзе.
Или у тебя академическая задача?
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302682
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myaucha,
насколько в курсе, спринг УЖЕ сделал вместо SQLExeption свои :
------------------
CannotAcquireLockException CannotSerializeTransactionException CleanupFailureDataAccessException ConcurrencyFailureException DataAccessException DataAccessResourceFailureException DataIntegrityViolationException DataRetrievalFailureException DeadlockLoserDataAccessException EmptyResultDataAccessException IncorrectResultSizeDataAccessException IncorrectUpdateSemanticsDataAccessException InvalidDataAccessApiUsageException InvalidDataAccessResourceUsageException OptimisticLockingFailureException PermissionDeniedDataAccessException PessimisticLockingFailureException TypeMismatchDataAccessException UncategorizedDataAccessException
-----------
это мало?
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302683
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123,
Я не отвечаю, когда обращение идет на ты, так что закончили дискуссию
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302687
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaЯ не отвечаю, когда обращение идет на ты, так что закончили дискуссию
О, как.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302694
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myaucha,
вики))
авторВ русском языке обращение «на вы» постепенно вошло в употребление с XVIII века из-за сильного влияния французского языка и культуры, прежде всего в кругах аристократии. Существуют теории, что исконно «вы» было обращением к врагу.
Удачи!
Работайте!
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39302840
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это не теория: "Иду на вы" - послание князя Святослава, которому было лень гоняться за разрозненными отрядами
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39303428
fsharp_fsharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaОсновная идея - привести DAO(JDBC) и DAO(Hibernate) к общему знаменателю, чтобы при подмене одного на другой не пришлось ничего меня в сервисе и контроллере. Для этих целей введены два новых исключения, расширяющие стандартные спринговые и более точно характеризующие ошибки.

правильно. только это не расширение. это изоляция слоев, чтобы ожидаемые DAO-исключения (конкурентный доступ, уникальность, FK и т.п.) не вылезали туда, куда им не стоит
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39303709
myaucha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fsharp_fsharpправильно. только это не расширение. это изоляция слоев, чтобы ожидаемые DAO-исключения (конкурентный доступ, уникальность, FK и т.п.) не вылезали туда, куда им не стоитВне зависимости от того, как это назовешь стандартная трансляция исключений в spring-е не до конца продумана.

Приведу пример. Предположим ни в DAO, ни в сервисе я не перехватываю исключений (то есть не подменяю своими, а использую стандартные спринговые) и делаю обработчик в контролере. Пусть у нас есть два DAO - для JDBC и для Hibernate. Пусть есть некая таблица в БД, в которой помимо первичного ключа еще два поля (например, user_name и email) должны быть уникальны. Тогда при нарушении уникальности на поле user_name в контроллер вернутся следующие исключения (предполагается, что имена ограничений в БД имеют семантический смысл и могут быть распарсены):

DAO-JDBC:
org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [insert into user_t (user_id, user_name, password, role_id, birthday, email) values (seq_id.nextval, ?, ?, ?, ?, ?)]; ORA-00001: нарушено ограничение уникальности (THIRD.USER$U$USER_NAME); nested exception is java.sql.SQLIntegrityConstraintViolationException: ORA-00001: нарушено ограничение уникальности (THIRD.USER$U$USER_NAME)

DAO-Hibernate
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [THIRD.USER$U$USER_NAME]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

Теперь на основе полученной информации мы хотим создать единый обработчик ошибок. Поскольку DuplicateKeyException наследует от DataIntegrityViolationException, то в обработчике надо предусмотреть обработку только DataIntegrityViolationException. Контроллеру, чтобы правильно вернуть пользователю информацию об ошибке (комментарий к полю формы ввода user_name или email), надо идентифицировать строку THIRD.USER$U$USER_NAME (для email строка будет THIRD.USER$U$EMAIL) как ограничение и разобрать ее. Для DAO-Hibernate это сделать просто - надо опуститься на уровень ниже и получить org.hibernate.exception.ConstraintViolationException, в котором заботливо предусмотрен метод getConstraintName. В DAO-Jdbc такой возможности нет и надо доставать имя ограничения прямо из сообщения. Спрашивается, что мешало создать метод (поле) getConstraintName в спринговом DataIntegrityViolationException и при реализации преобразований исключений для jdbc сделать его наполнение, раз уж эти исключения считаются стандартными?! Раз нет такой возможности, то в едином обработчике надо писать код, который бы еще проверял, а сидит ли на уровне ниже Hibernet-овское исключение или JDBC-ное (или еще какое-то), что уже криво. А с учетом того, что помимо реализации DAO может меняться и СУБД, то могут и еще какие-то проблемы всплыть.

Получается, чтобы сделать обработчик ошибок единым, надо вообще всегда брать getRootCause() и парсить исходную ошибку. И тогда от спринговых ошибок остается единственная польза - они рантаймовские. Понятно, что они поделены на группы и при анализе ошибки можно отделить DataIntegrityViolationException, например, от OptimisticLockingFailureException, но пример выше показывает, что этого недостаточно.
...
Рейтинг: 0 / 0
Hibernate - cохранение объекта
    #39303756
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
myauchaПусть у нас есть два DAO - для JDBC и для Hibernate
тема про хибер? Тогда при чём JDBC, да ещё попытка одного кода для JDBC и для ОРМ.
Кто на ком стоял?
Тебе бы тему переименовать чтобы не пудрить мозги:
Академико-теоретическая задача про универсальный код в DAL.
myauchaА с учетом того, что помимо реализации DAO может меняться и СУБД, то могут и еще какие-то проблемы всплыть.
и программисты могут меняться.
...
Рейтинг: 0 / 0
37 сообщений из 37, показаны все 2 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate - cохранение объекта
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]