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();
}
}
Пример Session Bean (Stateless) - Gallery Facade
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.
Ссылки
- Официальная страница продукта Enterprise JavaBeans на портале Oracle Архивная копия от 10 июня 2011 на Wayback Machine
- Спецификации различных версий Enterprise JavaBeans от SUN
- Краткое введение в технологию Enterprise JavaBeans (rus)(по версии 1.1) Архивная копия от 9 декабря 2007 на Wayback Machine
- Краткое введение в EJB3 Архивная копия от 11 сентября 2016 на Wayback Machine на Linux Format Wiki Архивная копия от 8 января 2014 на Wayback Machine, LinuxFormat 99
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.