nyxz
nyxz

Reputation: 7438

Cannot find EJB beanName on deploy

Hi @All :) I have a strange problem here. I want to inject UserBean managed entity in a class with the @EJB(beanName="user"). If I don't use the beanName attribute I get the following error message:

 org.jboss.as.server.deployment.DeploymentUnitProcessingException: No component found for type 'defaultPackage.UserBean' with name null  

If I use it like so @EJB(beanName="user") UserBean user; I get this:

 org.jboss.as.server.deployment.DeploymentUnitProcessingException: No component found for type 'defaultPackage.UserBean' with name user  

What am I doing wrong ?

Here is the UserBean and how I inject it:

UserBean

// removed imports
@ManagedBean(name="user")
@Local
@SessionScoped
@Entity
@Table(name="t_user")
public class UserBean implements Serializable, UserInterface{
    // fields (@Columns, etc.)
    // setters / getters
}

UserBeanUser

// more removed imports
@ManagedBean(name="userUsed")
@Stateful
@Local
public class UserOfUserBean implements Serializable, Userable {

    private @EJB(beanName="user") UserBean user;
}

The interfaces are empty and are marked as @Local.

Upvotes: 1

Views: 4625

Answers (1)

Arjan Tijms
Arjan Tijms

Reputation: 38163

I'm sorry, but this is wrong on so many levels that it's hard where to begin.

To start, the @Local annotation is useless on the code you show. It's used to mark an interface as a business interface for an EJB, or point to such an interface.

Then, the entity UserBean should probably not be scoped and a managed bean. These annotations are for letting the bean container manage the life-cyle of a bean, but in case of an entity it's the entity manager that is responsible for that.

It's not clear whether you used the JSF or Java EE ManagedBean annotation here, but the latter is never needed and the first shouldn't be needed as per the above explanation.

Additionally, per the typical conventions consider naming an entity just User and don't let it implement an interface.

UserOfUserBean is even harder to decipher. Is this bean supposed to be a business service or a (JSF) backing bean? If it's a backing bean, you don't need the @Stateful annotation and otherwise you don't need the @ManagedBean one.

Then, the major culprit of your question: the @EJB annotation can't inject non-EJB beans. JPA entities (@Entity) and JSF managed beans (@javax.faces.bean.ManagedBean) are not EJB beans.

Furthermore, the beanName attribute of @EJB does not correspond to the name attribute in @ManagedBean. The bean name is an EJB internal thing used to disambiguate an injection if an interface is implemented by multiple beans and has no relation to either the JSF managed bean name or the Java EE managed bean name. (not applicable to your question, but there is a relation between CDI's @Named and JSF's managed bean name)

Finally, entities nor backing beans need empty interfaces that are marked as @Local.

So, your entity should become something like:

@Entity
@Table(name="t_user")
public class User implements Serializable {
    // fields (@Columns, etc.)
    // setters / getters
}

And you should forget about injecting the entity the way you did. If you want to make it available in the HTTP session, put it there manually (e.g. after logging in). See this answer for a more elaborate explanation on how to do that: https://stackoverflow.com/a/6355064/472792

Assuming your UserOfUserBean was a backing bean, it would then become something like this with CDI:

@Named(name="userUsed")
public class UserOfUserBean {

    @Inject
    @LoggedIn // see answer from jan groth
    private User user;
}

or with JSF annotations only:

@ManagedBean(name="userUsed") // from javax.faces.bean, not javax.annotation
public class UserOfUserBean {

    @ManagedProperty("#{user}") 
    private User user;

    // Mandatory setter for JSF-native injection
    public void setUser(User user) {
        this.user = user;
    }
}

Some additional resources:

Upvotes: 3

Related Questions