Получить поле SessionScoped Bean через FacesContext - PullRequest
2 голосов
/ 24 ноября 2011

У меня есть следующие классы:

ClassA

import java.io.Serializable;

import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;

import timereport.db.UserBean;
import timereport.utils.JPAUtil;

@Named("classA")
@SessionScoped
public class ClassA implements Serializable {

    @Inject
    protected UserBean userBean;

    public void logout() {
        userBean = null;
    }

    public void login() {
        EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
        userBean = em.find(UserBean.class, userBean.getUsername());
    }

    //setter and getter for userBean
}

Здесь, в login() Я делаю

EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager();
userBean = em.find(UserBean.class, userBean.getUsername());

чтобы получить весь UserBean объект, и это правильно. Здесь возникает проблема ...

Класс B

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.sql.Date;
import java.util.List;
import java.util.ResourceBundle;

import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.log4j.Logger;

import timereport.db.UserBean;
import timereport.ClassB;
import timereport.utils.JPAUtil;

@Named("classB")
@SessionScoped
public class ClassB implements Serializable {

        @Inject private UserBean userBean;
        String throughUserBean = userBean.getUsername();
        ...
}

Здесь я не знаю почему, но я ожидал получить имя пользователя, установленное при входе пользователя в систему. И когда я вызываю @Inject UserBean или @Inject ClassB, я ожидаю, что они будут из одной и той же области видимости и удерживают Объект UserBean, который инициализируется при входе в систему. Но оба (classB и userBean) возвращают NULL, когда я ссылаюсь на них. Я ошибаюсь в своих ожиданиях установки этих объектов и есть ли другой способ сделать это?

Вот часть класса UserBean:

import java.io.Serializable;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;


import com.proxiad.timereport.utils.AESEncryptDecryptUtil;

@Named("user")
@SessionScoped
@Entity
@Table(name="t_user")
public class UserBean implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = -56986575421886097L;
    @Id
    @Column(name="username")
    private String username;
    @Column(name="fullname")
    private String fullname;
    @Column(name="password")
    private String password;
    @Column(name="email")
    private String email;
    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn (name="department", referencedColumnName="value")
    private ReferenceDataBean department;
    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="role", referencedColumnName="value")
    private ReferenceDataBean role;

    public UserBean() {}

    public String getFullname() {
        return fullname;
    }

    public void setFullname(String fullname) {
        this.fullname = fullname;
    }

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        try {
            this.password = AESEncryptDecryptUtil.encrypt(password);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public ReferenceDataBean getDepartment() {
        return department;
    }

    public void setDepartment(ReferenceDataBean department) {
        this.department = department;
    }

    public ReferenceDataBean getRole() {
        return role;
    }

    public void setRole(ReferenceDataBean role) {
        this.role = role;
    }

    @Override
    public int hashCode() {
        return getUsername().hashCode() + 17 * getEmail().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof UserBean) {
            UserBean user = (UserBean) obj;
            if (getUsername().equals(user.getUsername()) && getEmail().equals(user.getEmail())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public String toString() {
        return String.format("Username: %s\nEmail: %s\nDepartment:\n%s\nRole:\n%s\n", 
                getUsername(), getEmail(), getDepartment(), getRole());
    }

}

1 Ответ

3 голосов
/ 24 ноября 2011

Инъекция происходит после строительства. Введенные свойства не доступны во время строительства. Самая ранняя точка доступа к внедренным свойствам - метод @PostConstruct.

Итак, замените

@Inject private UserBean userBean;
String throughUserBean = userBean.getUsername();

от

@Inject private UserBean userBean;
String username;

@PostConstruct
public void init() {
    username = userBean.getUsername();
}

Это @Inject ClassB не имеет смысла, поэтому я удалил его.

...