Enterprise JavaBeans — Википедия

Enterprise JavaBeans (также часто употребляется в виде аббревиатуры EJB) — спецификация технологии написания и поддержки серверных компонентов, содержащих бизнес-логику. Является частью Java EE.

Эта технология обычно применяется, когда бизнес-логика требует как минимум один из следующих сервисов, а часто все из них:

  • поддержка сохранности данных (persistence); данные должны быть в сохранности даже после остановки программы, чаще всего достигается с помощью использования базы данных
  • поддержка распределённых транзакций
  • поддержка параллельного изменения данных и многопоточность
  • поддержка событий
  • поддержка именования и каталогов (JNDI)
  • безопасность и ограничение доступа к данным
  • поддержка автоматизированной установки на сервер приложений
  • удалённый доступ

Каждый EJB-компонент является набором Java-классов со строго регламентированными правилами именования методов (верно для EJB 2.0, в EJB 3.0 за счет использования аннотаций выбор имён свободный). Бывают трёх основных типов:

  • объектные (Entity Bean) — перенесены в спецификацию Java Persistence API
  • сессионные (Session Beans), которые бывают
    • stateless (без состояния)
    • stateful (с поддержкой текущего состояния сессии)
    • singleton (один объект на все приложение; начиная с версии 3.1)
  • управляемые сообщениями (Message Driven Beans) — их логика является реакцией на события в системе

Пример Entity Bean

[править | править код]
package org.test.entity;  import java.io.Serializable; import java.util.Date; import javax.persistence.*; import javax.validation.constraints.Size; import org.test.entity.listener.GalleryListener;  @Entity @EntityListeners({GalleryListener.class}) @Table(name = "gallery",     uniqueConstraints = {         @UniqueConstraint(columnNames = {"id"})     } ) @NamedQueries({     @NamedQuery(name = Gallery.QUERY_FIND_ALL, query = "SELECT g FROM Gallery g ORDER BY g.name ASC"),     @NamedQuery(name = Gallery.QUERY_FIND_BY_NAME, query = "SELECT g FROM Gallery g WHERE g.name = :name") }) public class Gallery implements Serializable {          private static final long serialVersionUID = 1L;          public static final String QUERY_FIND_ALL = "Gallery.findAll";     public static final String QUERY_FIND_BY_NAME = "Gallery.findByName";          @Id     @GeneratedValue(strategy = GenerationType.IDENTITY)     @Column(name = "id", nullable = false)     private Long id;          @Size(max = 100)     @Column(name = "name", length = 100)     private String name;          @Column(name = "created_at")     @Temporal(TemporalType.TIMESTAMP)     private Date createdAt;      public Gallery() {     }      public Gallery(String name) {         this.name = name;     }      public Date getCreatedAt() {         return createdAt;     }      public void setCreatedAt(Date createdAt) {         this.createdAt = createdAt;     }      public Long getId() {         return id;     }      public void setId(Long id) {         this.id = id;     }      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     }      @Override     public boolean equals(Object obj) {         if (obj == null) {             return false;         }         if (getClass() != obj.getClass()) {             return false;         }         final Gallery other = (Gallery) obj;         if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {             return false;         }         return true;     }      @Override     public int hashCode() {         int hash = 7;         hash = 47 * hash + (this.id != null ? this.id.hashCode() : 0);         return hash;     }      } 

Пример Entity Bean Listener

[править | править код]
package org.test.entity.listener;  import java.util.Date; import javax.persistence.PrePersist; import org.test.entity.Gallery;  public class GalleryListener {          @PrePersist     public void prePersist(Gallery gallery) {         gallery.setCreatedAt(new Date());     }      } 

Пример Session Bean - Stateless EAO (Entity Access Object)

[править | править код]
package org.test.eao;  import java.util.List; import javax.ejb.LocalBean; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.test.entity.Gallery;  @Stateless @LocalBean public class GalleryEAO extends AbstractEAO<Gallery> {          @PersistenceContext(unitName = "PersistenceUnit")     private EntityManager entityManager;      public GalleryEAO() {         super(Gallery.class);     }          @Override     protected EntityManager getEntityManager() {         return entityManager;     }          @TransactionAttribute(TransactionAttributeType.SUPPORTS)     public List<Gallery> findAll() {         return namedQuery(Gallery.QUERY_FIND_ALL).getResultList();     }          @TransactionAttribute(TransactionAttributeType.SUPPORTS)     public Gallery findByName(String name) {         return namedQuery(Gallery.QUERY_FIND_BY_NAME)                 .setParameter("name", name)                 .getSingleResult();     }    } 

Пример Abstract EAO (Entity Access Object)

[править | править код]
package org.test.eao;  import java.io.Serializable; import javax.persistence.EntityManager; import javax.persistence.Query; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root;  public abstract class AbstractEAO<T extends Serializable> {      protected abstract EntityManager getEntityManager();          private Class<T> entityClass;      public Class<T> getEntityClass() {         return entityClass;     }          public AbstractEAO(Class<T> entityClass) {         this.entityClass = entityClass;     }          public void persist(T entity) {         getEntityManager().persist(entity);     }          public void merge(T entity) {         getEntityManager().merge(entity);     }          public void remove(T entity) {         if (entity != null) {             getEntityManager().remove(entity);         }     }          public void remove(Object id) {         T entity = (T) getEntityManager().find(entityClass, id);         remove(entity);     }          public T find(Object id) {         return getEntityManager().find(entityClass, id);     }          public void refresh(T entity) {         getEntityManager().refresh(entity);     }          public TypedQuery<T> namedQuery(String queryName) {         return getEntityManager().createNamedQuery(queryName, entityClass);     }          public TypedQuery<T> query(String queryString) {         return getEntityManager().createQuery(queryString, entityClass);     }          public long count() {         CriteriaQuery criteriaQuery = getEntityManager().getCriteriaBuilder().createQuery();         Root<T> root = criteriaQuery.from(entityClass);         criteriaQuery.select(getEntityManager().getCriteriaBuilder().count(root));         Query query = getEntityManager().createQuery(criteriaQuery);                  return ((Long) query.getSingleResult()).longValue();     } } 
[править | править код]
package org.test.facade;  import java.util.List; import javax.ejb.*; import org.test.eao.GalleryEAO; import org.test.entity.Gallery; import org.test.exception.GalleryAlreadyExistsException; import org.test.exception.GalleryNotFoundException;  @Stateless @LocalBean public class GalleryFacade {          @Inject     private GalleryEAO galleryEAO;          @TransactionAttribute(TransactionAttributeType.SUPPORTS)     public Gallery findById(Long id) throws GalleryNotFoundException {         Gallery gallery = galleryEAO.find(id);         if (gallery == null) throw new GalleryNotFoundException("Gallery not found");         return gallery;     }          @TransactionAttribute(TransactionAttributeType.SUPPORTS)     public List<Gallery> findAll() {         return galleryEAO.findAll();     }          @TransactionAttribute(TransactionAttributeType.REQUIRED)     public void create(String name) throws GalleryAlreadyExistsException {         if (galleryEAO.findByName(name) != null) throw new GalleryAlreadyExistsException("Gallery already exists", name);         Gallery gallery = new Gallery(name);         galleryEAO.persist(gallery);     }         @TransactionAttribute(TransactionAttributeType.REQUIRED)     public void remove(Long id) throws GalleryNotFoundException {         Gallery gallery = findById(id);         galleryEAO.remove(gallery);     } } 

Пример Application Exception - GalleryNotFoundException

[править | править код]
package org.test.exception;  import javax.ejb.ApplicationException;  @ApplicationException(rollback=true) public class GalleryNotFoundException extends Exception {      public GalleryNotFoundException() {     }      public GalleryNotFoundException(String message) {         super(message);     }     } 

Пример Application Exception - GalleryAlreadyExistsException

[править | править код]
package org.test.exception;  import javax.ejb.ApplicationException;  @ApplicationException(rollback=true) public class GalleryAlreadyExistsException extends Exception {      private String name;          public GalleryAlreadyExistsException() {     }      public GalleryAlreadyExistsException(String message, String name) {         super(message);         this.name = name;     }      public String getName() {         return name;     }    } 

Литература

[править | править код]
  • Панда Д. EJB 3 в действии. — ДМК Пресс, 2014. — 618 с. — ISBN 978-5-97060-135-8.