[jboss-user] [JBoss Seam] - @PersistenceContext
msystems
do-not-reply at jboss.com
Fri Feb 1 18:21:31 EST 2008
I have a hard time to understand why a seam-managed persistence context (SMPC) @PersistenceContext behaves differently from a non-managed persistence context @PersistenceContext.
I know I have to use @In to use the SMPC entitymanger - but it looks like Seam also changes the behaviour for @PersistenceContext when SMPC is enabled.
Example - non-managed (expected behaviour):
| @Stateful
| @Name("authenticatorService")
| @Scope(ScopeType.SESSION)
| public class AuthenticatorBean implements AuthenticatorLocal {
| private static final String CONTEXT_PARAMETER_MAX_ATTEMPTS = "sine.login.max.attempts";
| private static final String CONTEXT_PARAMETER_TIME_LOCK = "sine.login.time.lock";
|
| @Logger
| private Log log;
|
| @PersistenceContext
| private EntityManager em;
|
| @In
| FacesMessages facesMessages;
|
| @EJB
| private UserLocal userService;
|
| @In(create = false, required = false)
| @Out(required = false)
| private User userDomain;
|
| @Out(required = false)
| private User loggedInUserDomain;
|
| private boolean authenticateError;
| private HashMap<String, Integer>loginAttempts = new HashMap<String, Integer>();
|
| public boolean authenticate() {
| authenticateError = false;
|
| userDomain = userService.getUserByUsername(Identity.instance().getUsername());
| if (userDomain != null) {
| if (userDomain.isTimeLocked()) {
| if (System.currentTimeMillis() - userDomain.getTimeLock().getTime()
| > (Long.parseLong(Util.getContextParameter(CONTEXT_PARAMETER_TIME_LOCK)) * 60000)) {
| loginAttempts.put(userDomain.getUsername(), 0);
| userDomain.setTimeLock(null);
| } else {
| facesMessages.addToControlFromResourceBundle("username", FacesMessage.SEVERITY_ERROR,
| "loginTimeLocked");
|
| authenticateError = true;
| return false;
| }
| }
|
| if (userDomain.getPassword()
| .equals(Password.encodePasswordMD5(Identity.instance().getPassword(), userDomain.getId()))) {
| if (!userDomain.isLocked()) {
| for (Role role : userDomain.getRoles()) {
| Identity.instance().addRole(role.getName());
| }
|
| loginAttempts.put(userDomain.getUsername(), 0);
| loggedInUserDomain = userDomain; // Store userDomain in Session
|
| return true;
| }
| }
| } else {
| log.info("Login error - user don't exist: {0}", Identity.instance().getUsername());
| }
|
| facesMessages.addToControlFromResourceBundle("username", FacesMessage.SEVERITY_ERROR, "loginError");
|
| authenticateError = true;
| return false;
| }
|
| @Observer(value = Identity.EVENT_LOGIN_FAILED, create = false)
| public void failedLoginEvent() {
| if ((userDomain != null) && !userDomain.isTimeLocked()) {
| int attempts = loginAttempts.containsKey(userDomain.getUsername())
| ? loginAttempts.get(userDomain.getUsername()) : 0;
|
| if (++attempts >= Integer.parseInt(Util.getContextParameter(CONTEXT_PARAMETER_MAX_ATTEMPTS))) {
| userDomain.setTimeLock(new Date());
| em.merge(userDomain); // I need to merge because entity is detached *************************** ATTENTION ***********
| em.flush();
| log.info("Time lock on user: {0}", userDomain.getUsername());
| } else {
| loginAttempts.put(userDomain.getUsername(), attempts);
| }
| }
| }
|
| public boolean isAuthenticateError() {
| return authenticateError;
| }
|
| @Remove // Seam needs this one for stateful beans
| public void destroy() {
| }
| }
|
Above example works fine and the database is updated correctly.
Example - SMPC (I don't need the merge anymore - looks like @PersistenceContext is extended, but why?):
| @Stateful
| @Name("authenticatorService")
| @Scope(ScopeType.SESSION)
| public class AuthenticatorBean implements AuthenticatorLocal {
| private static final String CONTEXT_PARAMETER_MAX_ATTEMPTS = "sine.login.max.attempts";
| private static final String CONTEXT_PARAMETER_TIME_LOCK = "sine.login.time.lock";
|
| @Logger
| private Log log;
|
| @PersistenceContext
| private EntityManager em;
|
| @In
| FacesMessages facesMessages;
|
| @EJB
| private UserLocal userService;
|
| @In(create = false, required = false)
| @Out(required = false)
| private User userDomain;
|
| @Out(required = false)
| private User loggedInUserDomain;
|
| private boolean authenticateError;
| private HashMap<String, Integer>loginAttempts = new HashMap<String, Integer>();
|
| public boolean authenticate() {
| authenticateError = false;
|
| userDomain = userService.getUserByUsername(Identity.instance().getUsername());
| if (userDomain != null) {
| if (userDomain.isTimeLocked()) {
| if (System.currentTimeMillis() - userDomain.getTimeLock().getTime()
| > (Long.parseLong(Util.getContextParameter(CONTEXT_PARAMETER_TIME_LOCK)) * 60000)) {
| loginAttempts.put(userDomain.getUsername(), 0);
| userDomain.setTimeLock(null);
| } else {
| facesMessages.addToControlFromResourceBundle("username", FacesMessage.SEVERITY_ERROR,
| "loginTimeLocked");
|
| authenticateError = true;
| return false;
| }
| }
|
| if (userDomain.getPassword()
| .equals(Password.encodePasswordMD5(Identity.instance().getPassword(), userDomain.getId()))) {
| if (!userDomain.isLocked()) {
| for (Role role : userDomain.getRoles()) {
| Identity.instance().addRole(role.getName());
| }
|
| loginAttempts.put(userDomain.getUsername(), 0);
| loggedInUserDomain = userDomain; // Store userDomain in Session
|
| return true;
| }
| }
| } else {
| log.info("Login error - user don't exist: {0}", Identity.instance().getUsername());
| }
|
| facesMessages.addToControlFromResourceBundle("username", FacesMessage.SEVERITY_ERROR, "loginError");
|
| authenticateError = true;
| return false;
| }
|
| @Observer(value = Identity.EVENT_LOGIN_FAILED, create = false)
| public void failedLoginEvent() {
| if ((userDomain != null) && !userDomain.isTimeLocked()) {
| int attempts = loginAttempts.containsKey(userDomain.getUsername())
| ? loginAttempts.get(userDomain.getUsername()) : 0;
|
| if (++attempts >= Integer.parseInt(Util.getContextParameter(CONTEXT_PARAMETER_MAX_ATTEMPTS))) {
| userDomain.setTimeLock(new Date());
| em.flush();
| log.info("Time lock on user: {0}", userDomain.getUsername());
| } else {
| loginAttempts.put(userDomain.getUsername(), attempts);
| }
| }
| }
|
| public boolean isAuthenticateError() {
| return authenticateError;
| }
|
| @Remove // Seam needs this one for stateful beans
| public void destroy() {
| }
| }
|
Above example works fine and the database is updated correctly, but I don't need to merge anymore - looks like @PersistenceContext is extended when running under SMPC.
Could someone explain why @PersistenceContext behaves differently under a SMPC?
Thanks.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4125702#4125702
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4125702
More information about the jboss-user
mailing list