Обычная версия
Java форум JavaTalks
форум программистов

Поиск   Пользователи   Группы   Регистрация 
 Профиль   Личные сообщения 

 Вход 

Загрузка полей до определённого уровня глубины
Список форумов
 ->  Персистентность в Java (JPA, ORM, ODB)


На страницу 1, 2, 3  След. 
Начать новую тему 
Предыдущая тема :: Следующая тема  
Автор Сообщение
plazman : 43
Новичок

СообщениеФев 17, 2012 13:05 
Ответить с цитатой
Например, есть у нас сущность

Partner (id, code, name, description, type)

И нам нужно грузить поля по необходимости, то есть в разных случаях по разному.
Вариант lazy и не lazy не прокатывает, так как это чёрно-белый вариант, а нежен цветной Smile

Например, какие варианты имеются ввиду в данном случае

1. Табличная форма: id, code, name, type (без description) HEADER_LEVEL
2. Форма для редактирования: id, code, name, type, description (всё) DETAIL_LEVEL
3. Комбобоксы: id, code, name (без description, type) LINK_LEVEL

Может это уже реализовано в Hibernate ???

Это простой пример, но иногда (если не всегда) сущности обрастают кучами связей и тянут за собой тонны ненужного мусора.
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Староверъ : 7629
Ктапубеп
Откуда: Elfland

СообщениеФев 17, 2012 14:13 
Ответить с цитатой
Похоже на ситуацию, когда нужно создать какой-то SearchRequest с набором полей, затем в зависимости от того какие из них там указаны как EAGER, устанавливать соответствующий fetch при создании критерии.
_________________
JTalks Open Source Project, JT Webinars, JT Interview
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
Skipy : 4805
Я тут живу!
Откуда: Москва, Россия

СообщениеФев 17, 2012 14:17 
Ответить с цитатой
plazman писал(а):
Это простой пример, но иногда (если не всегда) сущности обрастают кучами связей и тянут за собой тонны ненужного мусора.


Добро пожаловать в реальный мир. Это фундаментальная проблема ORM как подхода. Удовлетворительного решения не имеет.
_________________
С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других!
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Староверъ : 7629
Ктапубеп
Откуда: Elfland

СообщениеФев 17, 2012 14:28 
Ответить с цитатой
Цитата:
Удовлетворительного решения не имеет.
Хм.. самое простое решение - сделать несколько методов с разными фетч стратегиями. Та же проблема будет и в чистом JDBC, никакой разницы в данной ситуации нет.
Еще один вариант - замапить несколько классов на одни и те же таблицы по-разному, это для еще более сложных решений.
И третий вариант, для самых сложных проблем, - создать View, которая аккумулирует только нужные данные для данного вида запросов и замапить класс на нее.
_________________
JTalks Open Source Project, JT Webinars, JT Interview
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
plazman : 43
Новичок

СообщениеФев 17, 2012 17:06 
Ответить с цитатой
То есть проблема решается путём создания новых классов ?
На каждый случай свой класс ?

PartnerLink - LINK_LEVEL
PartnerHeader - HEADER_LEVEL
Partner - DETAIL_LEVEL

В каждом классе свои поля
Или я не правильно понял мысль ?
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
plazman : 43
Новичок

СообщениеФев 17, 2012 17:07 
Ответить с цитатой
to Староверъ
Если не затруднит, можно примерчик.

Я имел ввиду пример на это:
Цитата:
сделать несколько методов с разными фетч стратегиями


Спасибо.
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
plazman : 43
Новичок

СообщениеФев 17, 2012 17:28 
Ответить с цитатой
И ещё мысли вслуг...
А чем вообще вызвано, что в Hibernate или других ORM так болезненно относятся к загрузке полей по требованию БЕЗ ИЗМЕНЕНИЯ при этом маппинга, создания отдельных классов, методов и т.д.

Может это с чем то связано....как то совсем не верится, что это трудно в реализации...значит какая то причина есть.

Хотелось бы видеть что то типа...

Код:


/* Загрузить только поля code, name */
EntityManager.select(Partner.class, "code, name")

...

/* Загрузить только поля code, name и все поля  для свойства type кроме поля description */
EntityManager.select(Partner.class, "+code, name, type.* -type.description")



Просто куча народу из-за такой вот "МЕЛОЧИ" начинают создавать свои ORM...
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Староверъ : 7629
Ктапубеп
Откуда: Elfland

СообщениеФев 17, 2012 19:50 
Ответить с цитатой
Нужно просто понимать, ничего тут сложного нет. Если подумать, то как еще должен работать ORM? Какие предложения?
Во многих ситуациях просто ленивая инициализация дложна помочь, ты уверен, что ты понимаешь что и зачем делаешь? Может и тебе ленивая загрузка поможет?
Примеры не знаю какие привести - я предоставил несколько рецептов, вроде как там больше нечего описывать. Разные фетч стратегии - значит использование JOIN в HQL или EagerFetch в CriteriaAPI, что приводит к методам типа getUser(), getUserWithDogs(), getFullUser().
_________________
JTalks Open Source Project, JT Webinars, JT Interview
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
Vermut : 1063
Завсегдатай
Откуда: Ростов-на-Дону

СообщениеФев 17, 2012 22:17 
Ответить с цитатой
Skipy писал(а):
plazman писал(а):
Это простой пример, но иногда (если не всегда) сущности обрастают кучами связей и тянут за собой тонны ненужного мусора.


Добро пожаловать в реальный мир. Это фундаментальная проблема ORM как подхода. Удовлетворительного решения не имеет.

Это проблема вообще никакого отношения к ORM не имеет. Когда сущности начинают беспорядочно обрастать связями, нужно идти в книжный магазин брать книгу Эрика Эванса "Предметно-Ориентированное проектирование" и читать главы связанные с дистиляцией модели до тех пор пока не наступит просветление.

Что касается управления ленивой загрузкой то Старовер уже всё написал, нужную fetch стратегию легко варьировать выбирая необходимую в каждый конкретный момент вермени, при формировании запроса. Правда я погуглил минут 10 и не нашел как это сделать в JPA, возможно придеться спуститься на уровень родной ORM которая у Вас заюзана как реализация JPA, я правда никогда EntityManager не пользовался возможно задать тип фетча динамически можно и средствами самого JPA, но в принципе если это и нельзя, не вижу в этом ничего плохого чтобы использовать аннотации JPA на энтитях но вместо EntityManager пользоваться обычной Hibernate Session.
_________________
Познакомлюсь с привлекательной Ростовчанкой для совместного изучения Java
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
plazman : 43
Новичок

СообщениеФев 18, 2012 10:13 
Ответить с цитатой
Ну как я и подозревал...
элементарные вещи нельзя реализовать на популярном ORM аля Hibernate....
Мда...лучше 2 месяца потерять... на создание ORM, но потом за час долететь...чем всю жизнь мучиться
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Vermut : 1063
Завсегдатай
Откуда: Ростов-на-Дону

СообщениеФев 18, 2012 11:10 
Ответить с цитатой
Как человек уже написавший свою ORM Вам этого делать не советую. Если этим занятием и стоит заняться только в очень специфических случаях, я например писал свою как часть инструмента трансформации и синхронизации данных между разными СУБД, а в обычных проектах использую хибернейт.

Для хибернейта Ваш случай предельно простой. Допустим изначально связь между юзером и его правами ленивая, но появился юзкейс в котором права нужно загрузить сразу вмести с юзером одним SQL запросом просто приджойнив их. Тогда на Criteria API это будет так:
Код:

User user = (User) session.createCriteria(User.class)
                .setFetchMode("permissions", FetchMode.JOIN)
                .add( Restrictions.idEq(userId) )
                .uniqueResult();

ТеперЬ вам нужно разобраться как аналогичное делать с EntityManager.
_________________
Познакомлюсь с привлекательной Ростовчанкой для совместного изучения Java
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
Vermut : 1063
Завсегдатай
Откуда: Ростов-на-Дону

СообщениеФев 18, 2012 11:36 
Ответить с цитатой
Собственно в JPA тоже фетч стратегии можно настраивать, всё что нужно это прочитать документацию, пример аналогичный предидущему только для JPA:
Код:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery query = cb.createQuery(User.class);
Root<User> root = query.from(User.class);
query.where(cb.equal(root.get("id"), userId));
root.fetch("permissions", JoinType.LEFT);
User user = (User) query.getSingleResult();

Так что вместо написания собственной ORM читайте документацию в ней всё написано.
_________________
Познакомлюсь с привлекательной Ростовчанкой для совместного изучения Java
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
Vermut : 1063
Завсегдатай
Откуда: Ростов-на-Дону

СообщениеФев 18, 2012 12:15 
Ответить с цитатой
Ну а собственно как это все дело оформить красиво то можно так:
Код:

public class MediaDaoImpl implements MediaDao {

    ...
    @Override
    List<Single> findSingleByCriteria(SingleSearchCriteria singleCriteria) {
         Criteria criteria = session.createCriteria(Single.class);
         if (singleCriteria.joinArtist()) {
             criteria.setFetchMode("artist", FetchMode.JOIN)
         }
         if (singleCriteria.joinAlbum()) {
             criteria.setFetchMode("album", FetchMode.JOIN)
         }
         if (singleCriteria.getTitlePattern() != null) {
             criteria.addRestrictions(Restirctions.ilike("title"), singleCriteria.getTitlePattern())
         }
        ... настройка других параметров запроса
        return criteria.list();
    }
    ...

}

Пример показывает как искать песни с возможным динамическим выбором подгрузки артиста, альбома.

Так что Skipy попробуйте здесь найти фундаментальную проблему ORM Smile Всё вроде объектно-ориентированно и прозрачно, какой критерий сформирует клиент этого DAO такой результат и получит.
_________________
Познакомлюсь с привлекательной Ростовчанкой для совместного изучения Java
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
plazman : 43
Новичок

СообщениеФев 18, 2012 12:48 
Ответить с цитатой
Цитата:
Так что вместо написания собственной ORM читайте документацию в ней всё написано

Так там между строк чёрным по белому так и написано...
В Hibernate нельзя простым способом типа

Код:
EntityManager.select(Partner.class, "+code, name, type.* -type.description")


выполнить загрузку списка объектов по определённым полям.
для решения этой задачи мучайтесь с помощью феч методов типа

Код:

List<Single> findSingleByCriteria(SingleSearchCriteria singleCriteria) {
            Criteria criteria = session.createCriteria(Single.class);
            if (singleCriteria.joinArtist()) {
                criteria.setFetchMode("artist", FetchMode.JOIN)
            }
            if (singleCriteria.joinAlbum()) {
                criteria.setFetchMode("album", FetchMode.JOIN)
            }
            if (singleCriteria.getTitlePattern() != null) {
                criteria.addRestrictions(Restirctions.ilike("title"), singleCriteria.getTitlePattern())
            }
            ... настройка других параметров запроса
            return criteria.list();
       }


Действительно... зачем на всё упрощать...надо что бы всё было сложно и запутанно...при 10-ти вариантах загрузки нам всего лишь нужно 10 раз использовать условие if ()...

За любовь к Hibernate надо платить....


Цитата:
Как человек уже написавший свою ORM

Ну темплейт метод и полноценный ORM это немножко разные вещи...
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Vermut : 1063
Завсегдатай
Откуда: Ростов-на-Дону

СообщениеФев 18, 2012 13:12 
Ответить с цитатой
plazman писал(а):

В Hibernate нельзя простым способом типа

Код:
EntityManager.select(Partner.class, "+code, name, type.* -type.description")


Получается тот же самый HQL, плюсики минусики и звездочки не стоят того чтобы ради сокращения на несколько символов писать свою ORM. У тебя еще выходит что запрос статический, попробуй сформировать что-то сложное в зависимости от условий и быстро поймешь что склейка строк не вариант и Criteria API выглядит получше.
_________________
Познакомлюсь с привлекательной Ростовчанкой для совместного изучения Java
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
 
Начать новую тему  Тема закрыта
Страница 1 из 3
На страницу 1, 2, 3  След.
Список форумов
 -> Персистентность в Java (JPA, ORM, ODB)


 
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Java and all Java-related trademarks and logos are trademarks or registered trademarks of Oracle Corporation in the United States and other countries.
Это сайт не относится к фирме Oracle Corporation и не поддерживается ею.

© 2006-2010 www.javatalks.ru: форум java программистов
Используется скрипт phpBB © 2001, 2010 phpBB Group

Хостинг от bizname.ru