© HAULMONT, 2013
«Выбор фреймворков реализации ORM
и пользовательского интерфейса для
корпоративного приложения»
Константин Кривопустов
krivopustov@haulmont.com
О докладчике
2
© HAULMONT, 2013
– 15 лет в индустрии ИТ
– 10 лет опыта в Java
– технический директор Haulmont
• компания-разработчик корпоративных систем
• 100+ сотрудников в Самаре и Лондоне
– архитектор технологической платформы
Содержание
• Введение: обзор задач и архитектуры
приложений
• Часть 1: почему мы используем
OpenJPA, а не Hibernate
• Часть 2: применение Vaadin для
реализации пользовательского
интерфейса
3
© HAULMONT, 2013
Наши задачи и типы приложений
4
© HAULMONT, 2013
Корпоративные информационные системы
– Cложная модель данных
– Реляционная СУБД, динамические запросы
– Насыщенный UI, типовые компоненты
• Тиражируемые продукты
• Заказные решения
• Платформа CUBA
Часть 1: почему OpenJPA?
5
© HAULMONT, 2013
ORM ?
Hibernate
OpenJPA
EclipseLink
Data Nucleus
OpenJPA: модификация байткода
6
© HAULMONT, 2013
Отслеживание
изменений
Загрузка
по требованию
(lazy loading)
Hibernate: как он это делает?
7
© HAULMONT, 2013
Entities
Loaded
attribute
values
Persistence Context (Session)
Отслеживание
изменений
Загрузка
по требованию
(lazy loading)
Invoice
Persistence Context (Session)
Customer
Proxy
Customer
DB
Hibernate: проблемы
8
© HAULMONT, 2013
• Много объектов в контексте – долгий поиск
изменений при коммите
• Отсоединили объект от контекста – потеряли
информацию об изменениях
• Lazy OneToOne
Current Loaded DB
Managed Commit Detached Merge
Managed
(all attributes are dirty)
Пример сущности
9
© HAULMONT, 2013
60 полей
1 200 000 записей
testUpdateDetached
10
© HAULMONT, 2013
Start
transaction
Commit
transaction
Find a Case
instance by ID
Change one
attribute
Start
transaction
Merge Case
instance
Commit
transaction
testUpdateDetached: results
11
© HAULMONT, 2013
OpenJPA Hibernate
select CREATE_TS, /* 63 more */
from DN_CASE where ID = ?
2.1 ms 2.1 ms
select LAST_VISIT_DATE,
/* OpenJPA: 4 more, Hibernate: 63 more */
from DN_CASE t0 where ID = ?
1.1 ms 2.1 ms
update DN_CASE set LAST_VISIT_DATE = ?
where ID = ?
1.3 ms 1.3 ms
Merge JDBC time 2.4 ms 3.4 ms
Total test time 30 ms 30 ms
Тестовая модель данных
12
© HAULMONT, 2013
Debtor Case
1 *
Contractor
Address DebtorScore
Contract* 1
*
1
1 1
1
Debtor 800,000
Case 1,200,000
Contract 280
Contractor 800,000
Address 1,330,000
Экран списка Debtor
13
© HAULMONT, 2013
testDebtorBrowse: OpenJPA
14
© HAULMONT, 2013
select d from dn$Debtor d
join d.cases cas
left join d.contractor contr
where cas.contract.id = ?1
order by contr.contractorName
JPQL FetchPlan
Debtor.isCompany
Debtor.lastVisitDate
Debtor.contractor
Debtor.cases
Contractor.contractorName
Case.status
Case.contract
…
testDebtorBrowse: Hibernate
15
© HAULMONT, 2013
select d from dn$Debtor d
join d.cases cas
left join fetch d.contractor contr
left join fetch d.debtorScore ds
left join fetch d.mainAddress
left join fetch d.debtorActionsSettings
left join fetch d.callcentrePrioritySettings
where cas.contract.id = ?1
order by contr.contractorName
JPQL
@OneToMany(
mappedBy = "debtor",
fetch = FetchType.LAZY)
@OrderBy("oneStepId")
@BatchSize(size = 200)
private List<Case> cases;
Hint
testDebtorBrowse: results
16
© HAULMONT, 2013
OpenJPA Hibernate
select ID, …
/* OpenJPA: 61 more columns,
Hibernate: 156 more columns */
from DN_DEBTOR … /* 6 joins */
where …
89 ms 164 ms
select ID, …
/* OpenJPA: 7 more columns,
Hibernate: 65 more columns */
from DN_CASE
where DEBTOR_ID in (?, … /* 99 more params */)
20 ms 47 ms
JDBC time 109 ms 211 ms
Total test time 336 ms 383 ms
Ограничение списка полей
17
© HAULMONT, 2013
• FetchPlan
– Полноценные «недозагруженные» сущности со связями
– Простой единообразный подход к описанию
OpenJPA
• Projections + ResultTransformer
– Read-only плоские DTO или maps
• Lazy properties
– Статичное описание в модели, «все или ничего»
Hibernate
Чего нам не хватает в OpenJPA
18
© HAULMONT, 2013
• Ограниченный набор функций
– Только определенные стандартом JPQL
– Нужны функции SQL текущей СУБД
• Нет возможности выполнить LEFT JOIN … ON
– Иногда нужно задать условия внешнего соединения, не
помещая их в WHERE
– Hibernate: left join … with
• Не экранируются зарезервированные имена СУБД
– Проблемы при портировании
Тесты ORM
19
© HAULMONT, 2013
Используются:
• OpenJPA 2.2.1
• Hibernate 4.2.0.Final
• PostgreSQL 8.4, JDBC driver 9.1-901.jdbc4
• Junit 4.11
• JUnitBenchmarks 0.6.0
Скачать:
• http://files.cuba-platform.com/misc/ormt-openjpa.zip
• http://files.cuba-platform.com/misc/ormt-hibernate.zip
Часть 2: применение Vaadin
20
© HAULMONT, 2013
Vaadin
Client-Side
Engine
Client-Side UI
Components
(JavaScript)
Web Browser
Web Server
Vaadin
Servlet
Server-Side UI
Components
(Java)
Application Code
(Java)
Themes
(CSS)
HTTP
Архитектура Vaadin
Плюсы Vaadin
21
© HAULMONT, 2013
• Rich Web UI
– Функциональность сравнима с Swing
– Широкий набор компонентов
– Возможность создания своих компонентов
• Эффективность создания и сопровождения кода
– Только Java
– Весь прикладной код работает на сервере
Минусы Vaadin
22
© HAULMONT, 2013
• Память сервера
– СЭД «ТЕЗИС»: 10…20 MB на пользователя
• 500 пользователей – 10GB heap
• 1500 пользователей – 2x16GB heap
– Репликация HTTP-сессий ?
• Подходит для приложений, но не для сайтов
• Создание собственных компонентов на GWT
• Громоздкий код инициализации UI
Пример кода инициализации
23
© HAULMONT, 2013
Generic UI
24
© HAULMONT, 2013
XML Descriptors Java Controllers
Vaadin
Framework
Declarative
Layout
Пример компоновки экрана в XML
25
© HAULMONT, 2013
Generic UI
26
© HAULMONT, 2013
XML Descriptors Java Controllers
VCL Interfaces
Vaadin
Implementations
Swing
Implementations
Vaadin
Framework
Java Swing
Infrastructure Datasources
Web and Desktop implementation
27
© HAULMONT, 2013
Web Application
Desktop Application
Наши проблемы с Vaadin
28
© HAULMONT, 2013
• Быстродействие client-side
– Определяется производительностью JavaScript
• Изменение внешнего вида, темизация
– Vaadin 6: CSS, Vaadin 7: SCSS
• Отладка client-side кода
– Консоль, Пошаговая отладка средствами GWT
• Интеграция с JavaScript компонентами
– Vaadin 6: GWT-обертки, Vaadin 7: JavaScript API
• Расширение стандартных компонентов
– Собственный fork библиотеки
Ваши вопросы?
Спасибо за внимание!
29
© HAULMONT, 2013

JEEConf-2013 Krivopustov

  • 1.
    © HAULMONT, 2013 «Выборфреймворков реализации ORM и пользовательского интерфейса для корпоративного приложения» Константин Кривопустов krivopustov@haulmont.com
  • 2.
    О докладчике 2 © HAULMONT,2013 – 15 лет в индустрии ИТ – 10 лет опыта в Java – технический директор Haulmont • компания-разработчик корпоративных систем • 100+ сотрудников в Самаре и Лондоне – архитектор технологической платформы
  • 3.
    Содержание • Введение: обзорзадач и архитектуры приложений • Часть 1: почему мы используем OpenJPA, а не Hibernate • Часть 2: применение Vaadin для реализации пользовательского интерфейса 3 © HAULMONT, 2013
  • 4.
    Наши задачи итипы приложений 4 © HAULMONT, 2013 Корпоративные информационные системы – Cложная модель данных – Реляционная СУБД, динамические запросы – Насыщенный UI, типовые компоненты • Тиражируемые продукты • Заказные решения • Платформа CUBA
  • 5.
    Часть 1: почемуOpenJPA? 5 © HAULMONT, 2013 ORM ? Hibernate OpenJPA EclipseLink Data Nucleus
  • 6.
    OpenJPA: модификация байткода 6 ©HAULMONT, 2013 Отслеживание изменений Загрузка по требованию (lazy loading)
  • 7.
    Hibernate: как онэто делает? 7 © HAULMONT, 2013 Entities Loaded attribute values Persistence Context (Session) Отслеживание изменений Загрузка по требованию (lazy loading) Invoice Persistence Context (Session) Customer Proxy Customer DB
  • 8.
    Hibernate: проблемы 8 © HAULMONT,2013 • Много объектов в контексте – долгий поиск изменений при коммите • Отсоединили объект от контекста – потеряли информацию об изменениях • Lazy OneToOne Current Loaded DB Managed Commit Detached Merge Managed (all attributes are dirty)
  • 9.
    Пример сущности 9 © HAULMONT,2013 60 полей 1 200 000 записей
  • 10.
    testUpdateDetached 10 © HAULMONT, 2013 Start transaction Commit transaction Finda Case instance by ID Change one attribute Start transaction Merge Case instance Commit transaction
  • 11.
    testUpdateDetached: results 11 © HAULMONT,2013 OpenJPA Hibernate select CREATE_TS, /* 63 more */ from DN_CASE where ID = ? 2.1 ms 2.1 ms select LAST_VISIT_DATE, /* OpenJPA: 4 more, Hibernate: 63 more */ from DN_CASE t0 where ID = ? 1.1 ms 2.1 ms update DN_CASE set LAST_VISIT_DATE = ? where ID = ? 1.3 ms 1.3 ms Merge JDBC time 2.4 ms 3.4 ms Total test time 30 ms 30 ms
  • 12.
    Тестовая модель данных 12 ©HAULMONT, 2013 Debtor Case 1 * Contractor Address DebtorScore Contract* 1 * 1 1 1 1 Debtor 800,000 Case 1,200,000 Contract 280 Contractor 800,000 Address 1,330,000
  • 13.
  • 14.
    testDebtorBrowse: OpenJPA 14 © HAULMONT,2013 select d from dn$Debtor d join d.cases cas left join d.contractor contr where cas.contract.id = ?1 order by contr.contractorName JPQL FetchPlan Debtor.isCompany Debtor.lastVisitDate Debtor.contractor Debtor.cases Contractor.contractorName Case.status Case.contract …
  • 15.
    testDebtorBrowse: Hibernate 15 © HAULMONT,2013 select d from dn$Debtor d join d.cases cas left join fetch d.contractor contr left join fetch d.debtorScore ds left join fetch d.mainAddress left join fetch d.debtorActionsSettings left join fetch d.callcentrePrioritySettings where cas.contract.id = ?1 order by contr.contractorName JPQL @OneToMany( mappedBy = "debtor", fetch = FetchType.LAZY) @OrderBy("oneStepId") @BatchSize(size = 200) private List<Case> cases; Hint
  • 16.
    testDebtorBrowse: results 16 © HAULMONT,2013 OpenJPA Hibernate select ID, … /* OpenJPA: 61 more columns, Hibernate: 156 more columns */ from DN_DEBTOR … /* 6 joins */ where … 89 ms 164 ms select ID, … /* OpenJPA: 7 more columns, Hibernate: 65 more columns */ from DN_CASE where DEBTOR_ID in (?, … /* 99 more params */) 20 ms 47 ms JDBC time 109 ms 211 ms Total test time 336 ms 383 ms
  • 17.
    Ограничение списка полей 17 ©HAULMONT, 2013 • FetchPlan – Полноценные «недозагруженные» сущности со связями – Простой единообразный подход к описанию OpenJPA • Projections + ResultTransformer – Read-only плоские DTO или maps • Lazy properties – Статичное описание в модели, «все или ничего» Hibernate
  • 18.
    Чего нам нехватает в OpenJPA 18 © HAULMONT, 2013 • Ограниченный набор функций – Только определенные стандартом JPQL – Нужны функции SQL текущей СУБД • Нет возможности выполнить LEFT JOIN … ON – Иногда нужно задать условия внешнего соединения, не помещая их в WHERE – Hibernate: left join … with • Не экранируются зарезервированные имена СУБД – Проблемы при портировании
  • 19.
    Тесты ORM 19 © HAULMONT,2013 Используются: • OpenJPA 2.2.1 • Hibernate 4.2.0.Final • PostgreSQL 8.4, JDBC driver 9.1-901.jdbc4 • Junit 4.11 • JUnitBenchmarks 0.6.0 Скачать: • http://files.cuba-platform.com/misc/ormt-openjpa.zip • http://files.cuba-platform.com/misc/ormt-hibernate.zip
  • 20.
    Часть 2: применениеVaadin 20 © HAULMONT, 2013 Vaadin Client-Side Engine Client-Side UI Components (JavaScript) Web Browser Web Server Vaadin Servlet Server-Side UI Components (Java) Application Code (Java) Themes (CSS) HTTP Архитектура Vaadin
  • 21.
    Плюсы Vaadin 21 © HAULMONT,2013 • Rich Web UI – Функциональность сравнима с Swing – Широкий набор компонентов – Возможность создания своих компонентов • Эффективность создания и сопровождения кода – Только Java – Весь прикладной код работает на сервере
  • 22.
    Минусы Vaadin 22 © HAULMONT,2013 • Память сервера – СЭД «ТЕЗИС»: 10…20 MB на пользователя • 500 пользователей – 10GB heap • 1500 пользователей – 2x16GB heap – Репликация HTTP-сессий ? • Подходит для приложений, но не для сайтов • Создание собственных компонентов на GWT • Громоздкий код инициализации UI
  • 23.
  • 24.
    Generic UI 24 © HAULMONT,2013 XML Descriptors Java Controllers Vaadin Framework Declarative Layout
  • 25.
  • 26.
    Generic UI 26 © HAULMONT,2013 XML Descriptors Java Controllers VCL Interfaces Vaadin Implementations Swing Implementations Vaadin Framework Java Swing Infrastructure Datasources
  • 27.
    Web and Desktopimplementation 27 © HAULMONT, 2013 Web Application Desktop Application
  • 28.
    Наши проблемы сVaadin 28 © HAULMONT, 2013 • Быстродействие client-side – Определяется производительностью JavaScript • Изменение внешнего вида, темизация – Vaadin 6: CSS, Vaadin 7: SCSS • Отладка client-side кода – Консоль, Пошаговая отладка средствами GWT • Интеграция с JavaScript компонентами – Vaadin 6: GWT-обертки, Vaadin 7: JavaScript API • Расширение стандартных компонентов – Собственный fork библиотеки
  • 29.
    Ваши вопросы? Спасибо завнимание! 29 © HAULMONT, 2013