powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / EJB Session Bean
9 сообщений из 9, страница 1 из 1
EJB Session Bean
    #37647707
amigaboy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть JSF-бин, который инжектит EJB-бин (содержащий DAO для СУБД) аннотацией @EJB

В момент рендеринга страницы все методы EJB-бина отрабатывают на ура. Но страничка содержит js/ajax-элементы, которые обращаются к тому-же EJB-бину уже после рендеринга страницы (всплывающие диалоги итд). Так вот в момент их использования EJB уже не может обратиться к СУБД, ругается следующей ошибкой:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Caused by: java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.verifyOpen(EntityManagerImpl.java:1665)
	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:721)
	at ru.vac.pagecode.base.PageCodeBase.getNextDTOId(PageCodeBase.java:102)
	at ru.vac.pagecode.cl.InsCompany.saveNewCompany(InsCompany.java:37)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
	at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
	at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:153)
	... 36 more


EJB-бин и JSF-бин оба установлены как session. В чем может быть проблема?

ps: glassfish 3.1
...
Рейтинг: 0 / 0
EJB Session Bean
    #37647717
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну ок, у вас закырта сессия - вроде бы проблема кристально ясна. Показывайте код своего EJB.
...
Рейтинг: 0 / 0
EJB Session Bean
    #37647718
amigaboy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
package ru.vac.ejb;

import java.io.Serializable;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import ru.vac.jpa.common.CommonDTO;

@Stateless(mappedName = "ejb/PolisCommonEJB")
@SuppressWarnings("unchecked")
public class CommonEJB implements CommonEJBLocal {
	@PersistenceContext(unitName="VACJPA")
	private EntityManager em;
	
    public CommonEJB() { }

	public <T> List<T> findAll(Class<T> c) {
    	return (List<T>) em.createQuery("SELECT t FROM " + c.getSimpleName() + " t").getResultList();
    }

...итд
...
Рейтинг: 0 / 0
EJB Session Bean
    #37647726
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, вы что-то не то выложили. Вот это место надо: at ru.vac.pagecode.base.PageCodeBase.getNextDTOId (PageCodeBase.java:102) + что бы было видно, как в этот класс EntityManager инжектится.
...
Рейтинг: 0 / 0
EJB Session Bean
    #37647727
amigaboy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svenom,

все JSF-бины наследуются от PageCodeBase. В нем есть метод:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
public int getNextDTOId(CommonEJBLocal common, Class<? extends CommonDTO> c) {
	Query query = common.createQuery("SELECT MAX(v.id) FROM " + c.getSimpleName() + " v");
	List result = query.getResultList();
		
	if (result.size() > 0)
		return (Integer) result.get(0) + 1;
	
	return -1;
}


Из бина вызываться должен следующим образом:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
public class InsCompany extends PageCodeBase {
	private static final long serialVersionUID = 1L;
	
	@EJB
	private CommonEJBLocal common;

	public void saveNewCompany() {
		System.out.println(getNextDTOId(common, Inscompany.class));
	}
}


Я понимаю ситуацию, если JSF-бин помечен как request и после рендеринга страницы его уже не существует. Но он же session, значит и common должен оставаться в памяти до завершения пользовательского сеанса.
...
Рейтинг: 0 / 0
EJB Session Bean
    #37647732
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот это явно какой-то ппц:
Код: java
1.
2.
Query query = common.createQuery("SELECT MAX(v.id) FROM " + c.getSimpleName() + " v");
List result = query.getResultList();

Вы обратились к EJB: common.createQuery(). В этот момент он открыл сессию, создал объект Query и вернул его вам, потом закрыл сессию и транзакцию. Далее вы пытаетесь получить результат этот запроса, и он разумеется падает, так как EntityManager, через который вы получили Query был закрыт, все логично.
Что вам надо сделать? Ни в коем случае не давать объектам, которые зависят от подключения к БД (Query, Statement, ResultSet, сущности с Lazy-зависимостями и т.д..), "сбегать" ("escape") за пределы EJB, вся работа с БД должна обязательно происходить внутри бизнес-метода EJB.
...
Рейтинг: 0 / 0
EJB Session Bean
    #37647757
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svenomНу вот это явно какой-то ппц:
Код: java
1.
2.
Query query = common.createQuery("SELECT MAX(v.id) FROM " + c.getSimpleName() + " v");
List result = query.getResultList();

Вы обратились к EJB: common.createQuery(). В этот момент он открыл сессию, создал объект Query и вернул его вам, потом закрыл сессию и транзакцию. Далее вы пытаетесь получить результат этот запроса, и он разумеется падает, так как EntityManager, через который вы получили Query был закрыт, все логично.
Что вам надо сделать? Ни в коем случае не давать объектам, которые зависят от подключения к БД (Query, Statement, ResultSet, сущности с Lazy-зависимостями и т.д..), "сбегать" ("escape") за пределы EJB, вся работа с БД должна обязательно происходить внутри бизнес-метода EJB.

Почему вы думаете что после CommonEJBLocal.createQuery закроется транзакция, какой у этого метода атрибут транзакции?
Посмотрите в персистанс хмл какой используется датасорц и проветрте его валидность и попробуйте пропинговать, через менеджмент консоль апликейшин сервера
...
Рейтинг: 0 / 0
EJB Session Bean
    #37647760
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OOsalivanПочему вы думаете что после CommonEJBLocal.createQuery закроется транзакция, какой у этого метода атрибут транзакции?Потому что это явно следует из исключения - нету сессии, а значит нету и транзакции. Но при этом объект Query был создан, значит EntityManager внутри этого EJB живой, просто автор криво спроектировал свой EJB, бывает.
OOsalivanПосмотрите в персистанс хмл какой используется датасорц и проветрте его валидность и попробуйте пропинговать, через менеджмент консоль апликейшин сервераДа написано же - часть функций отрабатывают работу с БД нормально, а часть дуплит. Поэтому нечего в persistence.xml смотреть, там все в порядке.
...
Рейтинг: 0 / 0
EJB Session Bean
    #37647780
amigaboy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svenom,

спасибо. Перенес и создание запроса, и получения списка результатов в один метод в EJB - перестал ругаться.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / EJB Session Bean
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]