#java #dependencies #ejb #code-injection
#java #зависимости #ejb #внедрение кода
Вопрос:
я создал сеансовый компонент без состояния, подобный этому :
@WebServlet(name = "ProductController", urlPatterns = {"/ProductController"})
public class ProductController extends HttpServlet {
@EJB
private ProductFacadeBean productBean;
}
@Stateless
public class ProductFacadeBean extends AbstractFacade<Product> implements ProductFacadeLocalInterface {
@PersistenceContext(unitName = "OnlineStorePU")
private EntityManager em;
protected EntityManager getEntityManager() {
return em;
}
public ProductFacadeBean() {
super(Product.class);
}
}
@Local
public interface ProductFacadeLocalInterface {
void create(Product product);
void edit(Product product);
void remove(Product product);
Product find(Object id);
List<Product> findAll();
List<Product> findRange(int[] range);
int count();
}
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
public List<T> findAll() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return getEntityManager().createQuery(cq).getResultList();
}
public List<T> findRange(int[] range) {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
javax.persistence.Query q = getEntityManager().createQuery(cq);
q.setMaxResults(range[1] - range[0]);
q.setFirstResult(range[0]);
return q.getResultList();
}
public int count() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
cq.select(getEntityManager().getCriteriaBuilder().count(rt));
javax.persistence.Query q = getEntityManager().createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
}
}
Вопрос :
-
В чем ошибка? Как это решить?
javax.naming.Исключение NamingException: не удалось выполнить поиск ‘java:comp / env / Controller.ProductController /productBean’ в SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory , java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Корневым исключением является javax.naming.Исключение NamingException: Исключение, устраняющее Ejb для ‘Remote ejb-ref name=Controller.ProductController / productBean, удаленный интерфейс 3.x = EJB.ProductFacadeBean,ejb-link=null,lookup=,mappedName=,jndi-name=EJB.ProductFacadeBean,refType=Session’ . Фактическое (возможно, внутреннее) имя удаленного JNDI, используемое для поиска, — ‘EJB.ProductFacadeBean#EJB.ProductFacadeBean’ [Корневым исключением является javax.naming.Исключение NamingException: не удалось выполнить поиск ‘EJB.ProductFacadeBean#EJB.ProductFacadeBean’ в SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory , java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Корневым исключением является javax.присвоение имен.Исключение NameNotFoundException: EJB.ProductFacadeBean#EJB.ProductFacadeBean не найден]]]
Полное исключение прилагается здесь :
HTTP Status 500 -
type Exception report
message
descriptionThe server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: PWC1392: Error instantiating servlet class Controller.ProductController
root cause
com.sun.enterprise.container.common.spi.util.InjectionException: Error creating managed object for class Controller.ProductController
root cause
com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=Controller.ProductController/productBean,Remote
3.x interface =EJB.ProductFacadeBean,ejb-link=null,lookup=,mappedName=,jndi-name=EJB.ProductFacadeBean,refType=Session into class Controller.ProductController
root cause
javax.naming.NamingException: Lookup failed for 'java:comp/env/Controller.ProductController/productBean' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=Controller.ProductController/productBean,Remote
3.x interface =EJB.ProductFacadeBean,ejb-link=null,lookup=,mappedName=,jndi-name=EJB.ProductFacadeBean,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'EJB.ProductFacadeBean#EJB.ProductFacadeBean' [Root exception is javax.naming.NamingException: Lookup failed for 'EJB.ProductFacadeBean#EJB.ProductFacadeBean' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: EJB.ProductFacadeBean#EJB.ProductFacadeBean not found]]]
root cause
javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=Controller.ProductController/productBean,Remote
3.x interface =EJB.ProductFacadeBean,ejb-link=null,lookup=,mappedName=,jndi-name=EJB.ProductFacadeBean,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'EJB.ProductFacadeBean#EJB.ProductFacadeBean' [Root exception is javax.naming.NamingException: Lookup failed for 'EJB.ProductFacadeBean#EJB.ProductFacadeBean' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: EJB.ProductFacadeBean#EJB.ProductFacadeBean not found]]
root cause
javax.naming.NamingException: Lookup failed for 'EJB.ProductFacadeBean#EJB.ProductFacadeBean' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: EJB.ProductFacadeBean#EJB.ProductFacadeBean not found]
root cause
javax.naming.NameNotFoundException: EJB.ProductFacadeBean#EJB.ProductFacadeBean not found
note The full stack traces of the exception and its root causes are available in the GlassFish Server Open Source Edition 3.1 logs. GlassFish Server Open Source Edition 3.1
- Когда я создал сеанс для
компонент entity, использующий netbeans, удаляет его
создали абстрактный фасад для нас?
Какова цель? Я знаю фасад
шаблон должен служить интерфейсом для
направить запрос? - Какая польза от ejb-jar.xml ?
Все настройки по умолчанию. Компонент ejb создается внутри веб-приложения Java ee 6, а не в другом war или jar. Сервер Glassfish 3.1.
Пожалуйста, помогите.
Спасибо.
Комментарии:
1. Я надеюсь, что кто-нибудь может помочь по этой теме.
2. Проблема решена путем внедрения интерфейса, а не конкретного класса.
3. Зачем менять ProductBean на @EJB private ProductFacadeLocalInterface productBean и это работает?
4. Если интерфейс реализован двумя конкретными классами, как контейнер узнает, какой из них создавать?
5. Вы получили какой-либо ответ на свой последний вопрос?
Ответ №1:
Вам нужно внедрить компонент, ссылаясь на его интерфейс, а не на его реализацию напрямую. Что-то вроде этого..
@EJB
private ProductFacadeLocalInterface productBean;
Затем вы можете получить доступ к компоненту, используя методы интерфейса, которые вы представили в ProductFacadeLocalInterface
.
Комментарии:
1. Почему бы не внедрить реализацию напрямую, а не ее интерфейс? Если есть два класса, то мне нужно, чтобы мы отметили один класс значением premium.
2. Когда EJB, в вашем случае компонент без состояния, реализует какой-либо локальный / удаленный интерфейс, к нему необходимо получить доступ с помощью интерфейса. В JavaEE6 и EJB3.1 можно использовать интерфейсные компоненты без использования интерфейса и внедрять непосредственно реализацию, но этого следует избегать по соображениям дизайна и ремонтопригодности.
3. @aseychell Как насчет вопроса peterwkc? Если у вас есть 2 EJB, которые реализуют интерфейс, как контейнер узнает, какой из них выбрать?
4. @Unda Вы не можете. Вы должны создать локальный интерфейс для каждого компонента без состояния, который расширяет общий интерфейс.
Ответ №2:
вы должны использовать интерфейс. Если вы используете Seam Solder
и CDI
, вы можете указать точную реализацию с помощью
@Inject
@Exact(ProductFacadeBean.class)