EJB Advocate: EJB 2.x померла? (Исходники), Різне, Програмування, статті

У кожній статті EJB Advocate наводиться типовий діалог з реальними користувачами і розробниками в процесі надання рекомендацій щодо вирішення якої-небудь цікавої проблеми. Персональні дані учасників діалогу не повідомляються, також не використовуються недостатньо випробувані і закриті архітектури.


Теорія: Геть старе, хай живе новий!


Гей, EJB Advocate!


Пора прокидатися – кава готова! EJB 2.x померла! Хай живе EJB 3! Подивіться, наскільки спрощується життя при створенні персистентної об’єкта, такого, наприклад, як customer в одній з Ваших попередніх статей:






@Entity
@Table(name=”CUSTOMER”)
public class Customer implements Serializable {

private int id;
private String name;
private Order openOrder;

public Customer () {
super();
}

@Id
@Column(name=”CUST_ID”)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}

@Column(name=”NAME”)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

@OneToOne(cascade=CascadeType.ALL , fetch=FetchType.EAGER )
@JoinColumn(name=”OPEN_ORDER_ID”,referencedColumnName=”ORDER_ID”)
public Order getOpenOrder() {
return openOrder;
}
public void setOpenOrder(Order openOrder) {
this.openOrder = openOrder;
}
}


Потрібно всього лише створити простий POJO і анотувати його. Не потрібно нічого успадковувати. Не потрібно окремий home, інтерфейс або дескриптор розгортання. Крім того, не потрібно виконувати дії по відображенню для конкретного виробника програмного забезпечення!


Код в клієнтській програмі, що використовує EJB 3, ще простіше. Припустимо, я хочу отримати відкритий замовлення, пов’язаний з клієнтом, ключем якого є customerId з типом integer:






@PersistenceContext (unitName=”db2″)
EntityManager em;
try {
Customer c = (Customer)em.find(
Customer.class, new Integer(customerId)
);
Order o = c.getOpenOrder();
return o;
}
catch (EntityNotFoundException e) {
throw new CustomerDoesNotExist(customerId);
}

Оскільки один примірник EntityManager виступає в ролі home для всіх сутностей, не потрібно JNDI-пошук. Немає нічого простіше.


Так скажіть, навіщо є гамбургер після біфштекса?


Never Going Back (Ніколи не повертатися назад)


Досвід: Не поспішайте, потрібно враховувати компроміси


Шановний Never Going Back!


Оскільки тон Вашого листа кілька нахабнуватий, уїдливо зауважу, що EJB-компонент управління даними, про який Ви говорите, насправді являє собою частину інтерфейсу прикладного програмування Java Persistence API (JPA), що є окремою, але пов’язаної специфікацією JSR 220. Тому було б коректніше сказати: “використовувати JPA простіше”.


Якщо серйозно, то я радий, що Ви знайшли стандартний підхід до персистенції, який Вас влаштовує. Дуже багато моїх співрозмовники закінчували тим, що винаходили свій власний підхід до персистенції. Я вважаю, що слово “назад” в Вашого підпису “Ніколи не повертатися назад” означає, що ви не один з них.


Ризикуючи викликати Ваше невдоволення, EJB Advocate збирається дуже ретельно проаналізувати зазначені Вами переваги, щоб Ви могли правильно оцінити вигоди JPA в порівнянні з CMP-компонентами управління даними.




  1. JPA-компоненти управління даними – це не POJO


    Спочатку Ви згадали, що просто створюєте POJO і аннотіруете його (в числі іншого використовуючи @ entity) для створення компонента в стилі JPA. Все правильно. Але справедливості заради треба сказати, що більшість не вважає механізм персистенції заснованим на POJO, поки він не може бути використаний з існуючим (не модифікованим) простим Java-класом.


    Можна також згадати часи EJB 1.x, коли компоненти управління даними були більше схожі на POJO. Змінні примірника оголошувалися як частина реалізації компонента, який був конкретним класом. Ви “анотувати” клас шляхом оголошення його EJB-компонентом управління даними і реалізували методи управління життєвим циклом, такі як ejbLoad () і ejb Store () (або залишали їх для інструментальних коштів розгортання). Однією з причин відмови від них стало те, що вони завантажували CMP-поля за принципом все або нічого. Підхід EJB 2.x дозволяє гнучко покращувати продуктивність, наприклад, відображати методи get () на курсор бази даних або реалізацію потоку, зменшуючи кількість перетворень. JPA дозволяє “ліниву” завантаження властивостей через анотацію, але як ми побачимо далі, цей підхід створює свої власні проблеми, якщо вважати, що логічний об’єкт є POJO-об’єктом.



  2. JPA та EJB 2.x не вимагають створювати підклас (розширювати) якого-небудь конкретного класу


    Потім Ви згадали, що при використанні JPA нічого не потрібно “успадковувати”, маючи на увазі, що логічні об’єкти EJB 2.x це роблять. Таке припущення помилково. Уявіть типове оголошення класу компонента управління даними в EJB 2.x:





    public abstract class CustomerBean implements EntityBean …

    Клас (абстрактний чи конкретний), реалізує інтерфейс, насправді не успадковує нічого з інтерфейсу, який він реалізує. Реалізація інтерфейсу – це просто маркер того, що клас може виконувати дану роль в додатку, аналогічно дії, для якого призначена анотація @ entity.


    Ця відмінна риса дуже важлива, оскільки в тому, що стосується реалізації, Java підтримує тільки одинарне успадкування. Ви можете розширити тільки один клас і успадковувати його реалізації методів. Ви можете реалізувати стільки інтерфейсів, скільки забажаєте.


    А оскільки EJB 2.x-компоненти управління даними є абстрактним класом, немає необхідності реалізовувати будь-які з різних методів життєвого циклу EJB, пов’язаних з інтерфейсом EntityBean, наприклад, ejbLoad () і ejbStore (). Ці реалізації можуть бути покладені на інструментальні засоби розгортання, надані постачальниками програмного забезпечення.



  3. JPA-компоненти управління даними не підтримують кілька подань


    Далі Ви помітили, що не потрібно створювати інтерфейс або home в JPA-компонентах. Це правда. Але така простота є наслідок компромісу: Ви безпосередньо звертаєтеся до класу реалізації. Обмеження полягає в тому, що Ви отримуєте тільки одне подання компонента. Java-інтерфейси є потужними в тому плані, що можна надати подання компонентів реалізації, налаштовані під вимоги клієнта. EJB 2.x-компоненти управління даними підтримують концепцію відділення реалізації від інтерфейсів. Наприклад, можна надати як віддалене, так і локальне уявлення логічного об’єкта.


    Чому Ви хочете надати віддалений інтерфейс до EJB-компоненту управління даними, якщо найкращою відомою методикою є використання фасаду? В попередній статті EJB Advocate ми розповіли, як використовувати спеціалізовані home-методи компонентів управління даними для виконання ролі вбудованого фасаду. Оскільки фасад часто використовується віддалено, можна було б надати віддалений домашній інтерфейс, що включає один або декілька спеціалізованих методів, наприклад:





    public interface CustomerHome implements EJBHome {
    CustomerData ejbHomeGetOpenOrderForCustomer(int customerId) …
    }

    Зверніть увагу на те, що цей віддалений інтерфейс не має яких-небудь методів create () або find (). Це навмисне їх відсутність гарантує, що до примірника логічного об’єкта Customer ніколи не можна звернутися віддалено. Локальний і домашній інтерфейси до цієї ж реалізації компонента надавали б методи create і find разом з відповідними методами get та set (які, можливо, представляють собою CMR, як описано в ще одній статті EJB Advocate).


    І, як уже говорилося, більшість інструментальних засобів для EJB (наприклад, програмне забезпечення IBM Rational Application Developer for WebSphere) генерує інтерфейси і home за один крок за допомогою програми Wizard. Деякі навіть надають можливість почати з реалізації компонента (наприклад, POJO) і створювати методи для інтерфейсу і home в міру необхідності.



  4. JPA-компоненти управління даними вбудовують деталі реалізації в Ваші POJO-об’єкти


    Ще одне “перевага” JPA, згадане Вами, – можливість пропустити створення окремого дескриптора розгортання і дії по відображенню для конкретного постачальника програмного забезпечення. Все це добре (особливо в тому, що стосується стандартних відображень на сховища реляційних даних), але тут має місце компроміс. Ви вбудували деталі реалізації в код, що зробило об’єкт ще менш схожим на простий POJO, до якого Ви, мабуть, прагнете.


    Однією з найкращих функціональних можливостей EJB 2.x-компонентів управління даними є те, що при розгортанні можна змінити деталі реалізації персистенції даного бізнес-об’єкту абсолютно незалежно від провайдера компонента. Немає причин, через які провайдер не може прийняти аналогічний стандартний набір анотацій для відображення як частина дескриптора розгортання в стилі EJB 2.x, щоб спростити дії по відображенню.



  5. JPA-компоненти управління даними все ще краще використовувати за фасадом


    Нарешті, Ви правильно зазначили, що є тільки одна реалізація EntityManager, яка усуває необхідність виконувати JNDI-пошук і надзвичайно полегшує використання JPA-компонента управління даними. Однак Ви не згадали, що якщо не використовувати JPA-компонент в контексті транзакції, необхідно явно зберігати EntityManager для збереження будь-яких змін. Ще один аспект JPA, про який Ви забули згадати: якщо оголосити для компонента “ліниву” завантаження в анотаціях і потім відключити від контексту (тобто, кінець транзакції), то незаймані поля стають невизначеними.


    Необхідність явного управління контекстом транзакцій могла б ускладнити програмну модель JPA. Тому до цих пір найкращою методикою залишається використання сесійної фасаду (в новому стилі EJB 3 або в старому EJB 2.x). Якщо Ви виберете повернення POJO з фасаду, то Вам доведеться встановити значення завантаження в “eager” (активну) або торкнутися всі поля в JPA-сутності. При використанні спеціалізованих home-методів EJB 2.x сесія абсолютно не потрібна.


Очевидно, що більшість переваг EJB 3 та JPA, про які Ви згадали, має спрощують припущення, які можуть не працювати у всіх ситуаціях. Ви повинні самі вирішити, чи можете обійтися без цих припущень. Якщо це так, то, сподіваюся, Ви бачите, що майже всі вони можуть бути застосовані до специфікації EJB 2.x через інструментальні засоби розгортання. Нарешті, навіть специфікація JPA згадує, що EJB 2.x все одно, ймовірно, буде використовуватися після завершення розробки EJB 3 та JPA.


Отже (хай простить мене Марк Твен), EJB Advocate вважає, що чутки про смерть EJB 2.x сильно перебільшені.


Ваш EJB Advocate


Висновок


У цьому діалозі досліджені деякі фундаментальні питання простоти. Наприклад, що краще: мати складну систему, що забезпечує всю необхідну гнучкість, або просту систему, що полегшує роботу в стандартних ситуаціях? У наведених вище міркуваннях EJB Advocate запропонував: чому б не надати те й інше, забезпечуючи гнучкість, але також і варіант за замовчуванням, який робить речі простими?


Для тих, хто віддає перевагу об’єктно-орієнтований підхід до розробки додатків, EJB 2.x все ще може бути більш зручним, оскільки вона використовує всі можливості Java, що роблять його настільки потужним мовою програмування, особливо в плані відділення інтерфейсу від реалізації.


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*