繁体   English   中英

简单的CDI注入问题…在SessionScoped Controller bean中使用@Inject时,出现与“钝化”相关的错误

[英]Trouble with simple CDI Injection… “Passivation” related error when using @Inject in SessionScoped Controller bean

好的,我想我在这里犯了一个非常明显的错误,但是似乎无法通过我完成的几次Google / SO搜索找到答案。 我的Java编程背景主要基于JSF,在工作中,我只有使用Faces来管理我的bean的经验(使用@Managed批注)。 但是,我正在一个个人项目中尝试首次使用CDI。 我在将Service Bean注入SessionScoped控制器Bean时遇到了麻烦。这很奇怪,因为我将同一服务Bean注入到不同的RequestScoped Bean中没问题……我看不到我所缺少的内容。 我有实现了SerializableSessionScoped bean,但是当我尝试进行部署时,仍然出现以下错误, 只有在向bean中添加@Inject变量后(否则bean会变得毫无用处……): Caused by: org.apache.webbeans.exception.WebBeansConfigurationException: Passivation capable beans must satisfy passivation capable dependencies. 以下是我的服务和控制器Bean代码:

UserService.java

import ds.nekotoba.model.User;
import java.util.Date;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import org.apache.deltaspike.jpa.api.transaction.Transactional;
import org.apache.shiro.authc.credential.DefaultPasswordService;
import org.apache.shiro.authc.credential.HashingPasswordService;
import org.apache.shiro.crypto.hash.Hash;

@Named
@Transactional//Makes all methods in bean transactional
public class UserService {

    @Inject
    private EntityManager em;

    public User findById(Long id) {
        return em.find(User.class, id);
    }

    public User findByUsername(String username) {
        return em.createNamedQuery("User.findByUsername", User.class)
                .setParameter("username", username)
                .getSingleResult();
    }

    public User find(String username, String password) {
        List<User> found = em.createNamedQuery("User.find", User.class)
                .setParameter("username", username)
                .setParameter("password", password)
                .getResultList();
        return found.isEmpty() ? null : found.get(0);
    }

    @Produces
    @Named("users")
    @RequestScoped
    public List<User> list() {
        return em.createNamedQuery("User.list", User.class).getResultList();
    }

    public Long create(User user) {
        ….
    }

    public void update(User user){
        em.merge(user);
    }

    public void delete(User user){
        em.remove(em.contains(user) ? user : em.merge(user));
    }
}

LoginController.java注意:此bean中的@Inject调用没有问题!

import ds.nekotoba.model.User;
import ds.nekotoba.service.UserService;
import ds.nekotoba.util.Globals;
import java.io.IOException;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.omnifaces.util.Faces;
import org.omnifaces.util.Messages;

@Named(value="login")
@RequestScoped
public class LoginController {

    public LoginController() {
    }

    @Inject ProfileController profile;
    @Inject UserService userService;

    //Variables
    private String username;
    private String password;
    private boolean remember;

    //<editor-fold desc="Getters/Setters">
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public boolean isRemember() {
        return remember;
    }

    public void setRemember(boolean remember) {
        this.remember = remember;
    }
    //</editor-fold>

    public void submit() throws IOException {
        try {//Attempt login
            SecurityUtils.getSubject().login(new UsernamePasswordToken(username, password, remember));
        } catch (AuthenticationException ae) {
            Messages.addGlobalError("不明なユーザ、また試してみてください。");
            ae.printStackTrace();
        }

        //If successful, set User in ProfileController, get full user info 
        if(SecurityUtils.getSubject().isAuthenticated()){
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            profile.setUserInfo(user);
            //profile.refreshUserInfo(); //COMMENTED OUT DUE TO ERROR INJECTED IN ProfileController.java
        }

        //Redirect to intended page
        SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(Faces.getRequest());
        Faces.redirect(savedRequest != null ? savedRequest.getRequestUrl() : Globals.HOME_URL);
    }

}

ProfileController.java (一旦我在此bean中使用任何@Inject调用,上述错误就会显现出来……)

import ds.nekotoba.model.User;
import ds.nekotoba.service.UserService;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;

@Named(value="profile")
@SessionScoped
public class ProfileController implements Serializable {

    @Inject UserService userService;//CAUSES ERROR MENTIONED ABOVE

    //Variables
    private User userInfo;


    public ProfileController() {
    }

    public void refreshUserInfo() {
        userInfo = userService.findByUsername(userInfo.getUsername());
    }

    //<editor-fold desc="Getters/Setters">
    public User getUserInfo() {
        return userInfo;
    }

    public void setUserInfo(User userInfo) {
        this.userInfo = userInfo;
    }
    //</editor-fold>
}

就像我说的那样,我是CDI注射的新手,所以我确定我缺少明显的东西……我只是想不起来。 任何帮助将不胜感激。

其他项目信息:
JSF 2.2
JPA 2.0
TomEE 1.7.1
OmniFaces 1.8.1
Apache Shiro 1.3.0-快照
Apache DeltaSpike(这可能会引起冲突吗?)

Foo implements Serializable是必需的,但不足以使Foo可序列化。 Foo所有成员还必须可序列化。

在您的情况下, ProfileController可序列化,但其UserService成员不可序列化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM