Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / dirty checking, flush и т.д. / 25 сообщений из 26, страница 1 из 2
20.04.2017, 11:42
    #39441468
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Всем привет. Использую hibernate.
Есть метод в котором происходит простое чтение объекта:
Код: java
1.
2.
3.
4.
public void someMethod(long id){
   Person p = personRepository.findOne(id);
   p.setName("some name");
}


При выборе объекта он переходит в персистентное состояние, далее сетится имя и без явного save выходим из метода. В этот момент срабатывает dirty checking и флашит данные в базу.
Как можно обойти подобное поведение? Установка flush в manual не помогает. Ставить над каждым методом readOnly = true? Можно ли отключить механизм dirty checking-а? Спасибо
...
Рейтинг: 0 / 0
20.04.2017, 12:45
    #39441524
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
JulTКак можно обойти подобное поведение?

Есть предложение не обходить функциональностью, а пользоваться ей. Если вам нужно отсоединить сущность от сессии, есть Session.evict(), например.

JulTУстановка flush в manual не помогает.

Полагаю что вы ошиблись где-то в тесте.

JulTСтавить над каждым методом readOnly = true?

Вообще это хорошая практика для read only транзакций. Производительность можно улучшить значительно. Не обязательно ставить на все методы. Только на читающие.

JulTМожно ли отключить механизм dirty checking-а? Спасибо
Вроде нет:
https://hibernate.atlassian.net/browse/HHH-1041
...
Рейтинг: 0 / 0
20.04.2017, 13:13
    #39441554
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
JulTи без явного save выходим из метода. В этот момент срабатывает dirty checking и флашит данные в базу.
странно.
В базу пишется только при закрытии сессии хибера или при команде от вас в коде (update т .д.).
...
Рейтинг: 0 / 0
20.04.2017, 13:22
    #39441564
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Petro123В базу пишется только при закрытии сессии хибера или при команде от вас в коде (update т .д.).
При декларативном управлении транзакциями, сессия и транзакция через AOP привязываются к методу. Выход из метода закрывает сессию. Пора бы уже начать использовать Spring или хотя бы JEE.
...
Рейтинг: 0 / 0
20.04.2017, 13:23
    #39441565
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
BlazkowiczПора бы уже начать использовать Spring или хотя бы JEE.
Ты прав))
...
Рейтинг: 0 / 0
20.04.2017, 13:25
    #39441567
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Blazkowicz,
а почему у него тогда нет аннотаций над методом? Это же тогда ключевые вещи.
...
Рейтинг: 0 / 0
20.04.2017, 13:26
    #39441568
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Petro123а почему у него тогда нет аннотаций над методом? Это же тогда ключевые вещи.
У неё. Ну, нет и нет. Метод выдуманный. Проблема понятна и без аннотации.
...
Рейтинг: 0 / 0
21.04.2017, 10:53
    #39442101
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Blazkowicz, огромное спасибо за ответы.
Если я правильно поняла, то механизм dirty checking-а срабатывает всегда, кроме случаев, когда:
a) метод помечен аннотацией @Transactional с флагом readOnly = true
б) flushMode = MANUAL
Если readOnly=false на операцию чтения, то механизм dirty checking-а сработает в любом случае? Т.е., интересует в этом случае, на что хибер будет тратить время и почему это бъет по производительности. На сравнение сущности в момент загрузки и в момент выхода из метода и закрытия сессии?
При установке flushMode в MANUAL флаг readOnly игнорируется?
И еще хотелось бы узнать про транзакции.
Зависит ли срабатываение механизма dirty checking-а от того, помечен метод аннотацией @Transactional (без переопределения флага readOnly) или нет?
Как известно, если над методом не стоит аннотация @Transactional, при входе в метод запускается локальная транзакция, т.е. транзакция БД, правильно? В этом случае при выходе из метода происходит автоматический коммит?
Очень хочется узнать суть происходящего под капотом. Простите за сумбур
Спасибо
...
Рейтинг: 0 / 0
21.04.2017, 11:06
    #39442112
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
JulT,
если вы по факту пишите в объект, то почему вас так волнует readOnly?
...
Рейтинг: 0 / 0
21.04.2017, 11:25
    #39442124
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Petro123JulT,
если вы по факту пишите в объект, то почему вас так волнует readOnly?
согласна, но человеческий фактор еще никто не отменял
...
Рейтинг: 0 / 0
21.04.2017, 11:36
    #39442133
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
JulTсогласна, но человеческий фактор еще никто не отменял
согласен, но согласитесь, что так писать странно)) и глюкаво)
Как вариант:
- @Transactional с флагом readOnly просит спринг (прогер поставил)
- спринг просит ОРМ значит спринг просит хибер
- хибер САМ ставит FlushMode.NEVER в ТЕКУЩЕЙ сессии
- ваше p.setName("some name"); не будет сброшено в базу и пойдут глюки.
зы
Это минусы нашего AOP, несмотря на все наши плюсы.
...
Рейтинг: 0 / 0
21.04.2017, 11:48
    #39442142
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
JulTЕсли я правильно поняла, то механизм dirty checking-а срабатывает всегда, кроме случаев, когда:
a) метод помечен аннотацией @Transactional с флагом readOnly = true
б) flushMode = MANUAL

Нет. б) отключает dirty checking, а a) включает б)

JulTЕсли readOnly=false на операцию чтения, то механизм dirty checking-а сработает в любом случае?

Может не сработать, если Хибер не сумеет инструментировать сущность чтобы перехватить изменения свойств.

JulTПри установке flushMode в MANUAL флаг readOnly игнорируется?

Вы путаете ORM и управление транзакциями. Это две разных штуки. А вы их мешаете в кучу только потому что у вашего контейнера есть интеграция с ORM.

JulTЗависит ли срабатываение механизма dirty checking-а от того, помечен метод аннотацией @Transactional (без переопределения флага readOnly) или нет?
Как известно, если над методом не стоит аннотация @Transactional, при входе в метод запускается локальная транзакция, т.е. транзакция БД, правильно? В этом случае при выходе из метода происходит автоматический коммит?
Очень хочется узнать суть происходящего под капотом. Простите за сумбур

А ещё "локальность" транзакции тут тоже не при чем. Это антоним для XA транзакции. Вы много всего намешали в один вопрос.
...
Рейтинг: 0 / 0
21.04.2017, 12:01
    #39442164
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
JulTВсем привет. Использую hibernate.
Есть метод в котором происходит простое чтение объекта:
Код: java
1.
2.
3.
4.
public void someMethod(long id){
   Person p = personRepository.findOne(id);
   p.setName("some name");
}


1. после сеттера это уже не простое чтение объекта напр. из кеша.
2.
Если у вас не академический интерес, то не меняйте стратегию flush у хибера по умолчанию.
Разбирайтесь с транзакциями спринга уровнем выше.
Удачи!
...
Рейтинг: 0 / 0
21.04.2017, 20:57
    #39442537
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
...
Рейтинг: 0 / 0
21.04.2017, 21:05
    #39442538
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Тем не менее, для меня не совсем понятен один момент.
Если мы сделаем внутри транзакции сервлета:

Код: java
1.
2.
3.
4.
        userTransaction.begin();
        User user = entityManager.find(User.class, 60);
        user.setName("987");
        userTransaction.begin();



Ничего не изменится.

Но если сделаем тоже самое внутри EJB, то неявно будет выполнен persist? В чем логика?
...
Рейтинг: 0 / 0
21.04.2017, 21:06
    #39442539
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Во втором случае метод выглядит так:

Код: java
1.
2.
3.
4.
5.
6.
7.
    @TransactionAttribute(value = TransactionAttributeType.REQUIRED)
    public String getUserId(int id)
    {
        User user = entityManager.find(User.class, id);
        user.setName("753");
        return user.getName();
    }



Вроде как в первом и втором случае мы явно выполнили одно и тоже внутри транзакции. Но во втором был вызван persist?
...
Рейтинг: 0 / 0
21.04.2017, 21:18
    #39442547
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
BlazkowiczPetro123а почему у него тогда нет аннотаций над методом? Это же тогда ключевые вещи.
У неё. Ну, нет и нет. Метод выдуманный. Проблема понятна и без аннотации.
Оно и без аннотаций по дефолту TransactionAttributeType.REQUIRED
...
Рейтинг: 0 / 0
21.04.2017, 23:15
    #39442571
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Hett,
Что за код с двойным стартом транзакции?
...
Рейтинг: 0 / 0
22.04.2017, 09:14
    #39442607
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Где двойной старт?
...
Рейтинг: 0 / 0
22.04.2017, 09:24
    #39442608
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
А, да это когда сюда копировал ошибся. Там коммит.
...
Рейтинг: 0 / 0
22.04.2017, 10:03
    #39442612
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
без EJB нужно работать с сессией ОРМ-хибером. Закрыввать и открывать.
Hett
Код: java
1.
2.
3.
4.
5.
 
userSession.begin();
User user = entityManager.find(User.class, 60);
user.setName("987");
userSession.end();


кому что нравится
...
Рейтинг: 0 / 0
22.04.2017, 10:16
    #39442614
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
HettЕсли мы сделаем внутри транзакции сервлета:
у сервлета нет транзакции. Намешаны технологии.
Без EJB транзакция по поростому приравнивается к сессии хибера. Одно без другого не имеет смысла, т.к. они очень короткие и объекты живут от первой строчки сервлета до последней строчки.
...
Рейтинг: 0 / 0
22.04.2017, 12:12
    #39442646
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Я ошибся вчера видимо, в обоих случаях объект сохраняется без явного вызова persist или т.п.
...
Рейтинг: 0 / 0
22.04.2017, 12:16
    #39442647
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
Petro123HettЕсли мы сделаем внутри транзакции сервлета:
у сервлета нет транзакции. Намешаны технологии.
Без EJB транзакция по поростому приравнивается к сессии хибера. Одно без другого не имеет смысла, т.к. они очень короткие и объекты живут от первой строчки сервлета до последней строчки.

Транзакция это транзакция, естественно она не может существовать вне сессии.
Сессии есть у entityManager`a, приспокойно можно делать запросы на чтение, но транзакциями он не обеспечивает, и персист уже сделать не получится без явного или не явного использования транзакций.


Код: java
1.
userSession



Что это?
...
Рейтинг: 0 / 0
22.04.2017, 13:00
    #39442658
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dirty checking, flush и т.д.
HettЧто это?
псевдокод. Просто своя обёртка-код.
В интернете встречается как HibernateUtil.java
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
   Session session = HibernateUtil.beginTransaction(); 		
   try {
			Main u = new Main();
			u.setPassword("abc123");
			session.saveOrUpdate(u);
		} finally {
			HibernateUtil.commitTransaction();
		}

  // class HibernateUtil {
	public static Session beginTransaction() {
		Session hibernateSession;
		hibernateSession = HibernateUtil.getSession();
		hibernateSession.beginTransaction();
		return hibernateSession;
	}







package dao;

import main.Main;// пакет с DAO

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

public class HibernateUtil {
	private static SessionFactory factory;

	public static Configuration getInitializedConfiguration() {
		AnnotationConfiguration config = new AnnotationConfiguration();
		/* !!!!!!!!!!!!!!   // пакет с DAO */
		config.addAnnotatedClass(Book.class);
		config.addAnnotatedClass(Autor.class);
		config.configure();
		return config;
	}

	public static Session getSession() {
		if (factory == null) {
			Configuration config = HibernateUtil.getInitializedConfiguration();
			factory = config.buildSessionFactory();
		}
		Session hibernateSession = factory.getCurrentSession();
		return hibernateSession;
	}

	public static void closeSession() {
		HibernateUtil.getSession().close();
	}

	public static void recreateDatabase() {
		Configuration config;
		config = HibernateUtil.getInitializedConfiguration();
		new SchemaExport(config).create(true, true);
	}

	public static Session beginTransaction() {
		Session hibernateSession;
		hibernateSession = HibernateUtil.getSession();
		hibernateSession.beginTransaction();
		return hibernateSession;
	}

	public static void commitTransaction() {
		HibernateUtil.getSession().getTransaction().commit();
	}

	public static void rollbackTransaction() {
		HibernateUtil.getSession().getTransaction().rollback();
	}

	public static void main(String args[]) {
		HibernateUtil.recreateDatabase();
	}

}

...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / dirty checking, flush и т.д. / 25 сообщений из 26, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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