[英]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中没问题……我看不到我所缺少的内容。 我有实现了Serializable
的SessionScoped
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.