2015-01-19 3 views
0

Хорошо. Я предполагаю, что я делаю очень очевидную ошибку здесь, но я не могу найти ответ на него через несколько поисков Google/SO, которые я выполнил. Мой опыт программирования на Java в значительной степени основан на JSF, и на работе у меня есть опыт использования Faces для управления моими бобами (с использованием аннотации @Managed). Тем не менее, я работаю над личным проектом, в котором я пытаюсь использовать CDI в первый раз. У меня возникли проблемы с вводом компонента Service в компонентный компонент SessionScoped ... Это странно, потому что я вставляю тот же сервисный компонент в другой bean-компонент RequestScoped без проблем ... Я не вижу, чего мне не хватает. У меня есть компонент SessionScoped, реализующий Serializable, но я все еще получаю следующую ошибку при попытке развернуть: ТОЛЬКО после того, как я добавил переменную @Inject в bean-компонент (без которого компонент будет бесполезен ...): Caused by: org.apache.webbeans.exception.WebBeansConfigurationException: Passivation capable beans must satisfy passivation capable dependencies. немного моя служба и контроллер фасоли кода:Проблема с простой вставкой CDI ... Связанная с ошибкой «Пассивация» при использовании @Inject в компоненте SessionScoped Controller

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 Примечания: @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 (Ошибка упоминалось выше манифестов раз я использую любые @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> 
} 

Как я уже сказал, я новый пришелец в КДИ инъекции, поэтому я уверен, что мне не хватает чего-то очевидного ... Я просто не могу понять. Любая помощь будет принята с благодарностью.

Другая информация Проект:
JSF 2,2
JPA 2,0
TomEE 1.7.1
OmniFaces 1.8.1
Apache Shiro 1.3.0-SNAPSHOT
Apache DeltaSpike (это могло быть и противоположная точка ?)

ответ

2

Foo implements Serializable необходимо, но недостаточно для Foo для сериализации. Все члены Foo также должны быть сериализуемыми.

В вашем случае ProfileController является сериализуемым, но его членом UserService нет.

+0

Хорошо ... Итак, какие у меня варианты? Я просто реализую Serializable в UserService? Я не хочу менять его. Я должен попробовать это, когда вернусь домой. Спасибо за совет. – mousouchop

+0

Спасибо за этот улов, это была моя проблема. Теперь я понимаю, что класс шаблонов, который мы используем в проектах на работе, все реализует 'Serializable', как правило, поэтому я никогда раньше не сталкивался с этим конкретным исключением. Еще раз спасибо! – mousouchop

+0

Как указано в моем предыдущем комментарии - общая тенденция в моей работе - просто реализовать «Serializable» на всех компонентах Controller/Service/Model ... это обычная практика, чтобы избежать неожиданных и, казалось бы, случайных ошибок, таких как то, что я выше, когда вводится/разрешается экземпляр компонента? Есть ли лишние накладные расходы, связанные с этим подходом? Или это отраслевой стандарт? – mousouchop

Смежные вопросы