Implement SessionScoped Stateful bean in EntityListener

I am trying to implement some kind of audit in a Java EE JPA application on GlassFish 3.

I have added an annotation @EntityListenerson my object @MappedSuperclass, the listener has the annotation @PrePersistand @PreUpdateits methods, which are successfully used at runtime.

In these methods, I try to use ( @Inject) a @Named, @Stateful, @SessionScopedthe bean ( UserSession), to get the current user ID. The listener class has no annotations at all.

The problem is that I cannot enter a UserSessionbean; I always get the value null. At this point, I tried a simple @Inject UserSession us;one that always enters a null value. I also tried UserSession us = (UserSession) ctx.lookup("java:global/application/module/UserSession");that always returns a new object (I checked the constructor call, plus the object is empty).

I am sure I have missed something very important regarding CDI, but I cannot understand that. Can someone point me in the right direction?

+5
source share
3 answers

I ended up finding a workaround that allows me to get a @Statefulbean link :

I created a @Named @Singleton @Startupbean SessionController tag that contains a local one HashMap<String, UserSession> sessionMapwith links to my @Statefulbeans:

@Named
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class SessionController {

private HashMap<String, UserSession> sessionMap;

@PostConstruct
void init() {
    sessionMap = new HashMap<String, UserSession>();
}

@PreDestroy
void terminate() {
    for (UserSession us : sessionMap.values()) {
        us.logoutCleanUp(); //This is annotated as @Remove
    }
    sessionMap.clear();
}

public void addSession(String sessionId, UserSession us) {
    sessionMap.put(sessionId, us);
    System.out.println("New Session added: " + sessionId);
}

public UserSession getCurrentUserSession() {
    FacesContext context = FacesContext.getCurrentInstance();
    String sessionId = ((HttpSession) context.getExternalContext().getSession(false)).getId();
    return sessionMap.get(sessionId);
}

}

bean @PostConstruct:

public class UserSession implements Serializable {
@Inject SessionController sc;
...
    @PostConstruct
    void init() {
    FacesContext context = FacesContext.getCurrentInstance();
    String sessionId = ((HttpSession) context.getExternalContext().getSession(true)).getId();
    sc.addSession(sessionId, this);
}

.getSession(true), , . , this , @PostConstruct ...

EntityListener ( ) :

SessionController sc = (SessionController) new InitialContext().lookup("java:module/SessionController");
    UserSession us = sc.getCurrentUserSession();

CDI beans

@Inject SessionController sc;

, , , - ( FacesContext context = FacesContext.getCurrentInstance() ). beans (, , EntityListeners) @javax.jws.WebService @Stateless beans. ( : ) ( ), sessionId ( ). , , SessionContext bean sessionId - . , - ...

+1

EntityListners CDI, , JPA 2.0. , -, , JPA 2.1

, .

+2

@Inject UserSession us; .

, JPA 2.0 CDI, @Inject . CDI JPA 2.1 , .

UserSession us = (UserSession) ctx.lookup( "java: global/application/module/UserSession" );

beans, CDI JNDI. CDI BeanManager JNDI bean BeanManager. CDI, BeanManager "java: comp/BeanManager". :

InitialContext ctx = new InitialContext();
BeanManager bm = ctx.lookup("java:comp/BeanManager");
Set<Bean<?>> beans = bm.getBeans(UserSession.class);
Bean<?> bean = bm.resolve(beans);
CreationalContext<?> ctx = bm.createCreationalContext(bean);
UserSession us = (UserSession) bm.getReference(bean, UserSession.class, ctx);

bean, CDI, UserSession, .

, CDI- EntityListeners

+2
source

All Articles