javax.ejb.EJBException: недопустимый доступ к не бизнес-методу в представлении без интерфейса - PullRequest
12 голосов
/ 02 января 2012

Я использую EclipseLink в GlassFish 3.1.1 и пытаюсь понять это исключение:

javax.ejb.EJBException: Illegal non-business method access on no-interface view
    at org.mycompany.myproject.session.__EJB31_Generated__MyBeanFacade__Intf____Bean__.getEntityManager(Unknown Source)
    at org.mycompany.myproject.session.AbstractFacade.edit(AbstractFacade.java:28)
    at org.mycompany.myproject.controller.EditMyBeanServlet.doPost(EditMyBeanServlet.java:199)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)

Обратите внимание, что трассировка стека указывает, что проблема вызвана в сгенерированных Netbeans AbstractFacade.getEntityManagerМетод.

Есть идеи, что происходит, или какие-либо советы по устранению неполадок?Я предполагаю, что состояние транзакции или кэширования в EJB странно, когда это происходит, потому что иногда вызов метода edit работает нормально.Я вызываю методы EJB из сервлета.Исключение возникает при попытке сохранить изменения в объекте.

Ответы [ 3 ]

30 голосов
/ 03 января 2012

Ошибка, которую вы получаете, скорее всего, указывает на то, что ваш код все равно пытается вызвать защищенный метод. Это не разрешено для представлений без интерфейса на EJB. Вам разрешено вызывать только публичные методы.

Здесь есть небольшое несоответствие между нормальными правилами классов Java и правилами EJB. Для представления без интерфейса прокси создается на основе исходного типа класса (обычно его динамического подкласса). Таким образом, это означает, что защищенные и закрытые приватные методы видны для кода в одном и том же пакете, и что касается компилятора Java, ваш код может вызывать их.

Но, как уже упоминалось, это не разрешено правилами EJB, и, следовательно, создается исключение.

Вы можете легко воспроизвести это, введя боб, как показано ниже:

@Stateless
public class FooBean {

    public void callMe() {
    }

    protected void doNotCallMe() {
    }
}

Вставьте это куда-нибудь (например, сервлет в том же пакете) и попробуйте позвонить doNotCallMe(). Вы увидите то же исключение. Звоните callMe() и все будет хорошо.

4 голосов
/ 03 января 2012

Я думаю, что, возможно, нашел решение и, возможно, ошибку в программном обеспечении сторонних производителей.Кажется, что GlassFish 3.1.1 / EJB 3.1 / EclipseLink не может правильно обрабатывать перегрузку методов.У меня есть метод, определенный в моем EJB с именем edit, который перегружает (а не переопределяет) метод из родительского абстрактного класса.Есть метод с именем edit в абстрактном родительском объекте EJB, который принимает универсальный тип, а затем у меня есть метод с именем edit в EJB, который принимает List.Если я переименую метод в другое, чтобы он больше не перегружался, исключение исчезнет!

Код:

public abstract class AbstractFacade<T> {
protected abstract EntityManager getEntityManager();
public void edit(T entity) {
...

и

@Stateless
public class MyEntityFacade extends AbstractFacade<MyEntity> {
protected EntityManager getEntityManager() { return em; )
public void edit(List<MyEntity> entities) {
...

Примечание:Я заметил, что если я сделаю метод getEntityManager общедоступным вместо защищенного, я получу исключение TransactionRequiredException вместо EJBException.

0 голосов
/ 12 февраля 2014

Что странно, у меня была такая же проблема с внутренним классом моего EJB.При попытке вызвать закрытый метод parent или доступ к внедренному EJB я столкнулся с некоторыми проблемами.У меня было видение большинства вещей, но, наконец, рунета, все пошло не так.

Наконец, я решил получить свой родительский класс через JNDI, таким образом я мог без проблем вызывать публичный метод.Тем временем я мог бы вызывать все еще закрытые методы в классе моих родителей, я все еще должен помнить, что он потерпит неудачу.

...