开发者

Inject a Entity into a ViewScoped Bean

I am new to CDI and want to use this for a JSF2 application. The class MyUser is a simple @Entity-Bean and a object is created in a @PostConstruct method in bean:

@Stateful
@Named @javax.faces.bean.SessionScoped
public class UserBean implements Serializable
{
    @Named
    private MyUser user;

    //setter and getter
    //@PostConstruct
}

Accessing the user in a JSF pages works like a charm: #{user.lastName}. But now I want to access this object from other beans, e.g. in this @ViewScopedBean:

@Named @javax.faces.bean.ViewScoped
public class TestBean implements Serializable
{       
    @Inject private MyUser user;
}

I want the current (logged in) MyUser user to be available in a couple of other beans, but I'm not sure how to do this. Simply @Injecting it did not work (and I'm pretty sure this would be a litte bit to simple).

13:56:22,371 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController]
Error installing to Start: name=vfs:///Applications/Development/
jboss-6.0.0.Final/server/default/deploy/test.ear_WeldBootstrapBean state=Create:
org.jboss.weld.exceptions.DeploymentExc开发者_C百科eption: WELD-001408 Unsatisfied
dependencies for type [MyUser] with qualifiers [@Default] at injection
point [[field] @Inject private test.controller.mbean.TestBean.user]

What is the best approach to access the user from other beans? JSF1.2 style code like UserBean bean = (UserBean)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("UserBean"); seems seems to be old fashioned!


First of all: You don't want to directly inject entities. Entities are pretty independently controlled by the ORM-framework, and have their own life cycle. Don't use them as managed beans.

According to this definition, JPA entities are technically managed beans. However, entities have their own special lifecycle, state and identity model and are usually instantiated by JPA or using new. Therefore we don't recommend directly injecting an entity class. We especially recommend against assigning a scope other than @Dependent to an entity class, since JPA is not able to persist injected CDI proxies.

See here for details.

To answer your question: You cannot "outject" something like an (authenticated) user, even though this was possible in Seam 2, the whole proxy mechanism of CDI doesn't allow this anymore. What you need to do is the following:

  • Write a managed bean which handles the authentication and put it in the correct scope (probably session scope).
  • If login succeeds, use an attribute of this bean to store the authenticated user.
  • Use a producer method (probably with a qualifier like @LoggedIn) to make the user availabe in your application

Inject the user like this:

@Inject
@LoggedIn
private User user

That's the CDI-way ;-)


Is the @Inject ed bean a @Named bean, too?

If it is, has the MyUser bean a lesser scope than the TestBean. Remember that a @ViewScoped bean's managed properties have to be @ViewScoped, @SessionScoped or @ApplicationScoped


CDI does not specify a @ViewScoped annotation. This is a JSF2 annotation. The only possible annotations allowed are : @RequestScoped, @SessionScoped, @ApplicationScoped, @Dependent and @ConversationScoped. The first three are the only JSF scopes allowed by CDI.

If you need to support the @ViewScope annotation, you'll need write it yourself. Luckily, someone else has done this before.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜