Rectangle 27 1

Going back to your basic design, you'll have to reconsider if your "PlayerHandler" really is session scoped, conceptually. Since you require access to it outside the scope of a given session (a thread handling a request for a specific session), it looks like it is not.

One way to refactor this would be to move the "PlayerHandler" out to the application scope. Create a global singleton bean, call it "PlayerHandlerHolder" maybe, with a map that holds PlayerHandler instances keyed to session id, for instance. To prevent infinitely filling up this map, you could implement a session listener that removes PlayerHandler instances from the map on session destroy.

java - Spring MVC: session beans from two different sessions - Stack O...

java spring session spring-mvc
Rectangle 27 25

The @SessionAttribute annotation mentioned by @uthark is not suitable for this task - I thought it was too, but a bit of reading shows otherwise:

Session attributes as indicated using this annotation correspond to a specific handler's model attributes, getting transparently stored in a conversational session. Those attributes will be removed once the handler indicates completion of its conversational session. Therefore, use this facility for such conversational attributes which are supposed to be stored in the session temporarily during the course of a specific handler's conversation.

For permanent session attributes, e.g. a user authentication object, use the traditional session.setAttribute method instead. Alternatively, consider using the attribute management capabilities of the generic WebRequest interface.

In other words, @SessionAttribute is for storing conversation MVC-model objects in the session (as opposed to storing them as request attributes). It's not intended for using with arbitrary session attributes. As you discovered, it only works if the session attribute is always there.

I'm not aware of any other alternative, I think you're stuck with HttpSession.getAttribute()

I actually ended up using part of @uthark solution. To guard against exceptions caused by a null user context object, I put a ServletFilter in front to make sure it was populated. I'm ok with this solution for this particular workflow but it does seem weird that you can't handle a null value yourself instead of Spring dealing with it for you. Thanks everyone for the help and insight.

@skaffman Is there a reason the documents don't come right out and say controller instead of using the term handler?

java - Spring MVC Session Attribute Access - Stack Overflow

java spring spring-mvc
Rectangle 27 8

RequestContextHolder
class SecurityContextHolder {
    public static UserSecurityContext currentSecurityContext() {
        return (UserSecurityContext) 
            RequestContextHolder.currentRequestAttributes()
            .getAttribute("userSecurityCtx", RequestAttributes.SCOPE_SESSION));
    }
}
...
@RequestMapping("/myHomePage")           
public ModelAndView show() {           
    UserSecurityContext ctx = SecurityContextHolder.currentSecurityContext();
}

I kind of like this solution also. It's somewhat similar to a ThreadLocal pattern. Thanks!

java - Spring MVC Session Attribute Access - Stack Overflow

java spring spring-mvc
Rectangle 27 71

globalSession is something which is connected to Portlet applications. When your application works in Portlet container it is built of some amount of portlets. Each portlet has its own session, but if your want to store variables global for all portlets in your application than you should store them in globalSession. This scope doesn't have any special effect different from session scope in Servlet based applications.

java - Spring bean scopes: session and globalSession - Stack Overflow

java spring spring-mvc spring-ioc
Rectangle 27 5

@SessionAttributes("userSecurityContext")
public class UserSecurityContext {
}

@RequestMapping("/myHomePage")
public String show(@ModelAttribute("userSecurityContext") UserSecurityContext u) {
    // code goes here.
}

Thanks for the response. I'm adding my security context initially with session.putAttribute(). When I try your code, the context object is null.

Sorry, this did end up working when I added @SessionAttributes("userSecurityContext") to the controller. Simply adding it to the actual UserSecurityContext pojo didn't do anything for me. However an exception is thrown from Spring when the attribute is null which is what I'm trying to avoid. org.springframework.web.HttpSessionRequiredException: Session attribute 'userSecurityContext' required - not found in session

@Mark If this answer is not appropriate, please move the accepted flag (or remove it), as suggested by the answer below (by skaffman). This is misleading as many people read only the accepted answer. (just read your comment below - your call!)

java - Spring MVC Session Attribute Access - Stack Overflow

java spring spring-mvc
Rectangle 27 3

Your DataSource is probably being instantiated long before any request is made (note the bootstrap thread name in your log - [localhost-startStop-1]). So there is actually no SESSION which can be used by Spring to satisfy the SESSION scope.

You need to implement session-scoping manually (via RequestContextHolder) or have the components loosly coupled (e.g. via ApplicationContext#getBean).

What we have done on several projects is to implement TenantContext as ThreadLocal variable (similar to Spring Security's SecurityContext), which is being set and unset by a special servlet Filter. That is by far the best approach as no component will rely on the fact that there is actually an active HTTP request.

you would be better off without any session scoped bean

Sidenote: If you are using Hibernate, then be aware that there is already a support for multi-tenancy. Other frameworks might support it as well.

Thank you for your answer. One question: If the DataSource is being instantiated before any request is made that means it won't be possible to use a custom DataSource with setConnectionInitSqls. Right? Or simply haven't been executed the getConnection, so it's still possible to.

The ThreadLocal variable should be in a singleton bean?

DataSource is being instantiated before any request is made, however it is not used (i.e. getConnection is not called). You can still use setConnectionInitSqls. Regarding ThreadLocal - you can even place it as a static variable in some utility class (check Spring's RequestContextHolder or LocaleContextHolder).

One last question. Since all my multi-tenancy stuff is related to the logged in user, should I store the tenant information in the Authentication.getDetails() like this question says it's possible?. Do you see problems if I do it this way? (hope I'm not asking a fool's question)

That is a very good question. I always tend to keep tenant context logic independent. But you can definitely use security context to store tenant information. You only need to think about the situation when you don't have any user available (e.g. during authentication)... but that can be solved via docs.spring.io/spring-security/site/docs/3.0.x/reference/ (e.g. by creating temporary tenant specific anonymous authentication).

java - Spring. Access session Bean in my CustomDataSource getConnectio...

java spring spring-mvc multi-tenant session-bean
Rectangle 27 4

public class HomeController {
  @Autowired 
  private Cart cart; <-- Proxy

The Cart instance that gets injected into the HomeController instance is only a proxy that delegates method calls to the "real" instance. The Cart class itself has no own method or state yet, so you won't notice any difference between sessions, of course.

java - Spring session bean shared between HttpSession-s - Stack Overfl...

java spring spring-mvc session-bean
Rectangle 27 9

  • You use spring session beans for beans which are stateful and their state differs per user. These can be for example preferences of currently logged in user.
  • Default scope of bean in spring is singleton and it is no different in Web Application context.

Note than in web environment you can use also REQUEST scoped beans and their lifetime is only per one user request. You should use request scope when session is not necessary and request is sufficient.

Also, in portlet environment, you can use another scope which is GLOBAL SESSION. Each portlet has its own indepenednt session and typically those portlets are preffered to have their own state encapsulated only for themselves. But if you need to share session data among different portlets, you will need to use global session scope.

java - How exactly works the Spring session scope of a bean? what is t...

java spring spring-mvc
Rectangle 27 3

There's a lot of proxying and delegation going on.

@Autowired 
private Cart cart;

where Cart is session scoped will be proxied as you can see in your logs

com.at.test.web.Cart$$EnhancerByCGLIB$$2eb8334f

But this proxy is not wrapping a Cart object. It is wrapping a SimpleBeanTargetSource which takes care of getting a Cart bean from the BeanFactory.

Your bean definition attaches a SessionScope object which is responsible for checking your HttpSession through a static ThreadLocal field in RequestContextHolder. When request is made to get a bean from the BeanFactory, it will delegate the action to the SessionScope object which will check the HttpSession, use the one there if it exists or create and register a new one if it doesn't.

You don't notice this with your test because

cart.hashCode()

delegates to the SimpleBeanTargetSource object (incorrectly, if you ask me). But if you did

cart.toString();

you would see the difference as that actually reaches the underlying Cart object.

Depending on the scope and proxying strategy you use, all this may be different, but the end goal is still achieved.

java - Spring session bean shared between HttpSession-s - Stack Overfl...

java spring spring-mvc session-bean
Rectangle 27 7

So, from what I have understand it means that it is automatically created a single bean for each user session.

The session bean will be created per user, but only when requested. In other words, if, for a given request, you don't actually need that bean, the container will not create it for you. It's, in a sense, "lazy".

@Controller
public class MyController {
    @Autowired
    private MySessionScopeBean myBean;
    // use it in handlers
}

Here, you're injecting a session scoped bean into a singleton scope bean. What Spring will do is inject a proxy bean, that, internally, will be able to generate a real MySessionScopeBean object per user and store it in the HttpSession.

proxyMode = ScopedProxyMode.TARGET_CLASS

defines how Spring will proxy your bean. In this case, it will proxy by retaining the target class. It will use CGLIB for this purpose. An alternative is INTERFACES where Spring uses JDK proxies. These do not retain the class type of the target bean, only its interfaces.

You can read more about proxies here:

Here's a related post about the request scope:

java - How does the session scope of a bean work in a Spring MVC appli...

java spring spring-mvc spring-session
Rectangle 27 4

If you don't mind explicit solution, create a bean with session scope and inject it to your controller.

If you don't forget to wrap it with scoped proxy (<aop:scoped-proxy/>) you can just place your cached data in fields of that bean. Spring will automatically create one instance of that bean per each HTTP session and store it there.

On the other hand I think Spring caching abstraction might work for you - SPeL gives you access to HTTP environment so you probably construct cache key declaratively (in annotation) based on current user session id or some other attribute like user name.

session scoped bean is something I've considered, but rather as a way to implement simple caching by myself. And I really don't want to reinvent the wheel:) Caching abstraction with keys containing session id? Well, its interesting, but it still kips data application-wide, and now, even more data if user keeps logging in and out few times before old cached data is cleared. With sessions, at least, I know it will be thrown away as soon as session is invalidated.

If you go with caching abstraction approach (I am not sure whether this is possible but worth trying) you can easily plug your own cache by implementing org.springframework.cache.support.AbstractCacheManager.

Jeah, but still, it is implementing it by myself and probably will take more time :? On the other hand, it would have same interface :)

java - Simple session based data caching for spring mvc 3 - Stack Over...

java spring session caching spring-mvc
Rectangle 27 4

@RequestMapping(value="/")
  @Transactional
  public String getRespnse(Model m) {
        Session session =sessionFactory.getCurrentSession();
    //  List<User> usrLst=(List<User>) session.createQuery("from User");
    //  System.out.println("IN"+usrLst);
        return "home";
  }
  • Add @Transactional with your controller method

Thanks. It worked. That is so great.can you explain about this two motioned statement. that would be so much helpful to me in future

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

java - Spring MVC & Hibernate Could not obtain transaction-synchronize...

java spring hibernate spring-mvc
Rectangle 27 7

session - Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.

global session - Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.

java - Spring bean scopes: session and globalSession - Stack Overflow

java spring spring-mvc spring-ioc
Rectangle 27 6

What you posted works, but you aren't taking advantage of Spring's autowiring capabilities. What if you had many services or other beans to inject into your MyInterceptor bean.

Instead just make a @Bean method for your MyInterceptor

@EnableWebMvc
@ComponentScan(basePackages = {"com.whatever"})
@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Bean
    @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
    public UserSession userSession() {
        return new UserSession();
    }

    @Bean
    public MyInterceptor myInterceptor() {
        return new MyInterceptor(); // let Spring go nuts injecting stuff
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor()); // will always refer to the same object returned once by myInterceptor()
    }

    ...
}

How to inject session scope bean in interceptor using java config with...

java spring session spring-mvc interceptor
Rectangle 27 1

model.addAttribute("activeuser", activeuser);

The OP is using session and not the request.

I believe the redirect: prefix will generate a 302 redirect http response and session will be created, so getting the session attribute into the redirected handler must get the session attribute.

request.getSession().setAttribute("activeuser", activeuser);

Does not matter different request can give the same session. That's the point of the session: to be the same in between requests (either with forward or redirect).

That would be true if he obtains it direct from HttpSession.

java - Spring MVC Session Attribute - Stack Overflow

java spring model-view-controller
Rectangle 27 7

Ans 1) session scope is very similar to HttpSession scope. Beans instantiated based on session scope scope lives through the HTTP session. Similar to request scope, it is applicable only for web aware spring application contexts.

/** * Annotation-based configuration of session scope */ 
@Component
@Scope("session") 
public class ShopCart { }

and then

@Inject
private ShopCart cart;

java - How exactly works the Spring session scope of a bean? what is t...

java spring spring-mvc
Rectangle 27 4

refers to an appropriate subclass of WebApplicationContext. You're instantiating a AnnotationConfigApplicationContext which is not a subtype of WebApplicationContext and which does not register the SESSION and REQUEST scopes.

It also makes very little sense to create a brand new ApplicationContext in your @RestController. The @RestController object is already a bean within a Spring WebApplicationContext. Just add your new request scoped @Bean to that context and autowire into your controller.

Ok thanks, this makes a situation a bit more clear. However I still have some doubts regarding the proper usage (I have just started learning spring). How can I access the automatically instantiated WebApplicationContext? I have tried with Autowired - with no result. Also trying to access the request scoped bean via Autowired in RestController finishes with Exception at application startup.

@Mikolaj You're presumably using Spring MVC with a DispatcherServlet. This DispatcherServlet is loading its own WebApplicationContext (check your config). That's where you should declare your request scoped bean. You can then autowire it normally into your controller.

java - Spring RESTful Web service and bean "request" and "session" sco...

java spring spring-mvc
Rectangle 27 1

Session scoped beans are stored in Http Session by Spring framework. This scope is valid only in the context of Web application.It also works for Portlet envionments . When using in Portlet environment, there are two notions of session, application scope and portlet scope (default).

java - Spring "session" scope of a bean - Stack Overflow

java spring scope
Rectangle 27 1

Spring MVC creates for all method parameter new instance minimizes the potential risk of null pointer exception in your controller methods! But beware, this doesn't apply for wrapper types and classes with custom HandlerMethodArgumentResolver which can yield null as return value.

To answer your question, Spring MVC instanciates a new instance of your model class even the session expired. It can never be null!

ModelAttributeMethodProcessor

Model attributes are obtained from the model or if not found possibly created with a default constructor if it is available.

If no default constructor is available Spring MVC throws a BeanInstantiationException exception

org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [entity.Product]: No default constructor found

You can remove all null pointer checks safely.

For a overview of what Spring MVC can handle in controller methods by default you should take a look at code and javadoc in spring-web artefact package org.springframework.web.method.annotation and spring-webmvc artefact in package org.springframework.web.servlet.mvc.method.annotation.

java - Spring MVC: Is it necessary to test if a @ModelAttribute is nul...

java spring session spring-mvc modelattribute
Rectangle 27 7

What's happening is your servlet-context.xml is overwriting beans in your root-context.xml because it's declaring a component-scan for the package containing the @Repository class. In servlet-context.xml, you have

com.myportal.portal.model
ApplicationContext
<tx:annotation-driven>
HibernateDao
@Controller
root-context.xml

to your root-context.xml and removing <context:annotation-config/> (it is redundant). You then want to modify the component-scan in the servlet-context.xml to something more specific that doesn't contain the package of the @Repository classes

<context:component-scan base-package="com.myportal.portal.controllers" />

that package would contain your @Controller classes. You also don't need the <context:annotation-config>.

Ok, I changed it.Now I have problem with creating been: Error creating bean with name 'hibernateDao' defined in file [I:\Spring\vfabric-tc-server-developer-2.8.1.RELEASE\base-instance\wtpwebapps\portalSpol\WEB-INF\classes\com\myportal\portal\model\HibernateDao.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/util/TraceClassVisitor

I added asm and cglib dependency and this error disappeared. Now I have:No mapping found for HTTP request with URI [/portal/] in DispatcherServlet with name 'appServlet'. So I think that <context:component-scan base-package="com.myportal.portal.controllers" /> doesn't see my controllers (controllers are in this package). before modification it worked fine.

ok, now it works fine. Thanks for your help, your advices are helpful for me.

java - Spring MVC - No Hibernate Session bound to thread - Stack Overf...

java spring hibernate spring-mvc