Inject a Entity into a ViewScoped Bean

只愿长相守 提交于 2020-01-03 02:28:33

问题


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.DeploymentException: 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!


回答1:


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 ;-)




回答2:


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




回答3:


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.



来源:https://stackoverflow.com/questions/6343416/inject-a-entity-into-a-viewscoped-bean

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!