Im really new to java, jsf, jsp, and I need to learn how it works quickly. So the website Im using to practise has some terms etc that I dont know what they mean and Im hoping somebody can explain what they mean and how/what they are used for:)
Requestscoped
Applicationscoped
Sessionscoped
EntityManager
and could someone walk me through what these lines do?
#RequestScoped
public class Dao {
#DataRepository
#Inject
private EntityManager entityManager;
First of all, in Java (5 and higher), "things" starting with a # (e.g. #Deprecated) are called annotations.
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Your JavaBeans needs to be configured to a scope if you want to use it in JSF (Definitions can be found here).
#RequestScoped: Objects with this scope are visible from the start of the request until the end
of the request. Request scope starts at the beginning of a request and ends when the
response has been sent to the client. If the request is forwarded, the objects are visible
in the forwarded page, because that page is still part of the same request/response
cycle. Objects with request scope can use other objects with none, request, session,
or application scope. If you have to think it in terms of servlet, the managed bean is stored in the HttpServletRequest until the end of the request (when the response is sent to the client). After that, the bean no longer exists in the request.
#SessionScoped: An object with session scope is visible for any request/response cycle that
belongs to a session. Objects with this scope have their state persisted between
requests and last until the object or the session is invalidated. Objects with session
scope can use other objects with none, session, or application scope. Basically, these objects are stored in a HttpSession (refer to Servlets again). Each session has a session ID (known as JSESSIONID) that the bean is associated with.
ApplicationScoped: An object with application scope is visible in all request/response cycles
for all clients using the application, for as long as the application is active. In terms of Servlet, this could be, managed bean stored in a ServletConfig.
#NoneScoped: Objects with this scope are not visible in any JSF page. When used in the configuration file, they indicate managed beans that are used by other managed beans in the application. Objects with none scope can use other objects with none scope.
For EntityManager, this is associated with persistence context. It is used to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities. For more, refer to the JPA (Java Persistence API) Specification, or Hibernate.
#Inject, means that the instance is injectable. They follow the infamous crase word of Depency Injection or Inversion of Control (IOC). What this basically mean, is that when the resource (in your case EntityManager entityManager is needed, the JEE container instantiates the resource for you (without you needed to instantiate it directly through e.g. a constructor, etc.).
I have no clue what #DataRepository means. Never seen it before.
I hope this helps you.
These terms are usually associated with a dependency injection framework like guice and not with java in particular.
http://code.google.com/p/google-guice/wiki/Scopes describes the various scopes that are built into guice.
By default, Guice returns a new instance each time it supplies a value. This behaviour is configurable via scopes. Scopes allow you to reuse instances: for the lifetime of an application (#Singleton), a session (#SessionScoped), or a request (#RequestScoped). Guice includes a servlet extension that defines scopes for web apps. Custom scopes can be written for other types of applications.
Related
I have copied a sample Spring Boot SPA. I want to understand, what happens if multiple people use the web page via the URL. Does Java create an instance of the web application per call? Memory resources are not shared, right, i.e. if there is a list object appended to, each user sees their own list?
The default scope for a spring-boot bean is a singleton. Assuming your bean is not managing state you should be fine with the default behavior:
https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html
4.4.1 The singleton scope
When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with
an id or ids matching that bean definition will result in that one
specific bean instance being returned by the Spring container.
To put it another way, when you define a bean definition and it is
scoped as a singleton, then the Spring IoC container will create
exactly one instance of the object defined by that bean definition.
This single instance will be stored in a cache of such singleton
beans, and all subsequent requests and references for that named bean
will result in the cached object being returned.
Now if you are using a bean that's stateful and want a new bean used per request, you can define the scope of that bean to be prototype:
4.4.2 The prototype scope
The non-singleton, prototype scope of bean deployment results in the creation of a new bean instance every time a
request for that specific bean is made (that is, it is injected into
another bean or it is requested via a programmatic getBean() method
call on the container). As a rule of thumb, you should use the
prototype scope for all beans that are stateful, while the singleton
scope should be used for stateless beans.
Spring resources like #Service and #Repository and #RestController are stateless singletons. Only a single instance is created to serve the application.
Your implementation of the list at scope level will determine whether or not it is shared. If you define the List in the Controller, as in your example, then every user will have access to the same list. You can use multiple browsers to see that the list is shared. Based on the example, this is fine, as getting "all" should really mean getting all.
If you wanted each user to have their own list, you would have to implement some sort of Session or back-end process to associate each individual user with their own list.
This isn't shared-nothing like PHP or Rails. Java is so slow starting up that firing up a new instance of the application for every request isn't an option.
Check out the spring-boot sample application source code, there's a main method on the SpringbootJQueryAjaxClientApplication class, like this:
public static void main(String[] args) {
SpringApplication.run(SpringBootJQueryAjaxClientApplication.class, args);
}
this is the main method like for any Java program, what happens here is it starts the self-hosted servlet container and installs the application into it, then waits for http requests.
It is one process, where every request is served by a thread, so memory is shared. Spring components like com.javasampleapproach.jqueryajax.controller.RestWebController (scoped as singleton by default) are instantiated once in the web application, and every request calls methods on the same instance.
I am using Guice in a project. Since it is the first time, I am wondering about how to keep and pass around state, i.e. objects that contain some user input or long lived objects that are needed elsewhere (not where they were injected the first time).
For instance, my application has a Server which the user can start and stop. Furthermore, the user can enter some data which leads to state that needs to be preserved in memory.
At the moment I see two possibilities:
have a Context class with scope #Singleton and some references to other classes that keep my state and offer me certain functionality.
The Context class would give me access to the Server instance, to user data, other services etc.
The instances of the Context may be injected by Guice.
Thus, if I want to stop my server, I would require the Context as a dependency (and not the server).
This goes a bit against the recommendation on the Guice website (inject direct dependencies instead of accessing the "real" dependency with chained getters).
annotate all classes with #Singleton that should exist only once and are injected in several other classes. As a consequence, I would have only a singleton server, somewhere a class with the user data, etc.
The singleton pattern (GoF) is said to be bad design. Thus, I am wondering whether I should minimize the use of #Singleton or whether this is a different story using Guice respectively dependency injection in general.
Are there any other possibilities or a better approach?
I think most of your questions is related to Dependency Injection Paradigm. first of all Using DI doesn't mean every managed bean should be Singleton. The managed beans have their own life cycle. they can be instantiated on every access / request / session or being singleton.
The other thing you should be care about is with DI we usually wire-up our main application design. you should think of your domain objects and their relations instead of DI(Guice/Spring).
for instance in your case if you need a Service Object in a bean so you have the relationship between these two classes and no need to to have a relation to Context!
if data inserted by different users are visible to all users so make the service singleton in your application. if the states of Server bean for each user are different so make the scope of bean Session to allow every user have his own Server bean.
I have been trying to learn about the Java beans in WebSphere Commerce but I got really confused. Please help me out. I need to know:
What is the difference between EntityBean, SessionBean,
DataBean and AccessBean and how do they compare?
Though I found the difference between Session and Entity, and between Access and Data, I fail to understand how they are all related to each other.
All the help would highly be appreciated.
The entity bean represents a java bean which is coded by EJB specification and this java class is used to identify a record in a table.
Session bean is also a java bean following the EJB specification ; but this bean can be considered equivalent to a java class which has business logic with or without interacting with entity bean(i.e DB Data). Therefore a Session bean e.g ProcessRegistrationBean will act on a entity bean e.g PersonBean.
Now, for the second part of the question on what is access and databean : these two beans are extensions of Entity beans provided by Websphere application providing convenient access to the entity beans hiding the complexity of JNDI lookup and home/remote interface methods of EJB spec.
This means that if you want to get a user's info, you can easily do so as just creating the UserAccessBean(which is generated from entity bean for user) via it's no arg constructor and then initialize by setting the user id. AccessBean behind the scenes uses home interface to access remote interface and all those EJB stuff happens without you need to know them explicitly - therefore making it easier for the developer.
Databean are extensions of its corresponding access beans i.e UserDataBean extends UserAcessBean.
The suggested use of AccesBean is in the java layer e.g SessionBean (this also means you don't have to deal with entity bean directly ) and DataBean in the JSP layer. This is how all these are related
In Java nearly any class is called a bean. So don't confuse with that.
The different bean-terms you show are concepts of the function a class has in your application.
Usually the entity bean represents some entity of your domain. A user, a book, a car or what ever. Usually having some properties (firstname, lastname etc). An abstracted (or conceptual) object of your domain.
Unfortunately in EJB entity bean is meant as a bussiness controller for a domain object handling all complex actions that a domain object can be involved into (like create new book with dependencies, sell book, order book and whatever your domain allows to do with a book). All of your use-cases.
The domain object itself (a book) with its properties (title, ISBN number, price, amount of pages) is represented by a data bean, which usually maps to some database tables and rows.
The session bean usually is some kind of a container for information bound to the session of a user (and thus has some lifecycle, as the users session will expire). This could be information, if the user is authenticated or which data the user is currently editing. Therefor the session bean should have a pointer to a entity bean representing the users core data.
The access beans seem to be some clones on the "Data Access Object / DAO" pattern. This are application wide classes that allow you to access entities by providing methods like "getUserByUsername" or find methods for different searches and encapsulate accessing databases and other storages.
I am using a JEE6 stack including JPA 2.0, JSF 2.0, EJB 3.1 etc.
The way my architecture is setup is the following:
I have JPA annotated DAOs using hibernate as my JPA provider.
I have JSF Managed beans which correspond to my facelet/xhtml pages.
I have EJBs that handle all of my database requests.
My XHTML pages have JSF EL which make calls to my Managed beans. My managed beans contain references to my DAO entities which are managed by EJBs. For example, I have a user entity which is mapped to a db table. I have a user EJB which handles all CRUD operations that return Users. I have a page that edits a user. The highlevel workflow would be: navigate to user edit page -> EL calls a method located in the managed bean that loads a user. The method calls userEJB.loadUser(user) from the EJB to get the user from the database. The user is edited and submit -> a function is called in the managed bean which calls a function in the EJB to save the user. etc.
I am running into issues accessing my data within my JSF pages using EJBs.
I am having a lot of problems with lazy initialization errors, which I believe is due to how I have set things up.
For example, I have a Client entity that has a List of users which are lazily loaded. In order to get
a client I call a method in my EJB which goes to the database, finds a client and returns it. Later on
i wish to access this clients list of users, in order to do so i have to go back to the EJB by calling some sort of method in order to load those users (since they are lazily loaded). This means that I have to create a method such as
public List<User> getUserListByClient(Client c)
{
c = em.merge(c); return c.getUserList();
}
The only purpose of this method is to load the users (and I'm not even positive this approach is good or works).
If i was doing session management myself, I would like just leave the session open for the entire request and access the property directly, this would be fine as the session would be open anyway, there seems to be this one extra layer of indirection in EJBs which is making things difficult for me.
I do like EJBs as I like the fact that they are controlled by the container, pooled, offer transaction management for free etc. However, I get the feeling that I am using them incorrectly, or I have set up my JSF app incorrectly.
Any feedback would be greatly appreciated.
thanks,
If i was doing session management
myself, I would like just leave the
session open for the entire request
and access the property directly, this
would be fine as the session would be
open anyway
Indeed, that's the open session in view pattern (also called open EntityManager in view). It can be used with EJB as well. Ideally, the transactions should be managed in the business layer/EJB so this can be seen a slight deviation from the pure layer architecture. But it solves the problem of lazy loading in the view and is easy.
Otherwise, you must make sure to eagerly load the information that will be used after the transaction is over. Or you may rely on DTO, but then it starts to be cumbersome.
Here are two more links that cover the topic and discuss pros/cons and alternatives:
SO question: Open Session In View Pattern
Xebia blog: JPA implementation patterns and especially this one
Your usage seems good. Just remember that em.merge(c) may save the changes made to Client c into the database. If you just want to get the UserList of Client c without saving the changes made to the Client c, then you can do this:
public List<User> getUserListByClient(Client c)
{
Client client = em.find(Client.class, c.clientId);
return client.getUserList();
}
Or better ,just send the Client Id to the getUserListByClient instead of passing a full Client object , just to save a tinsy winsy bit of memory :)
First off, I think I'm trying to use Spring incorrectly, but confirmation would be appreciated.
I am trying to reset a single bean in mid-application. My initial configuration works just fine.
My scenario
1 Insurance Claim bean (session
scope)
1 Claim details bean which is a
multiactionController
(getClaim&setClaim enabled, prototype
scope)
1 Claimant details bean which is a
multiactionController
(getClaim&setClaim enabled, prototype
scope)
1 Submit claim bean which is a
multiactionController
(getClaim&setClaim enabled, prototype
scope).
My application is more complex than this, but for the sake of providing a clear example I wont describe the whole thing.
The first two controllers are used to set various properties of the claim, validate etc.
The third writes a claim to the database. THEN I want it to reset the bean. However I can't just say claim=new Claim() in SubmitClaimController.OnSubmit() as the ApplicationContext keeps its reference to the old Claim.
I could just create a method Claim.clear(), but that feels like the wrong approach. However, I can't see anything like ApplicationContext.destroyBean(beanname) or ApplicationContext.createBean().
I do not want to refresh the entire ApplicationContext as I will have other beans I want to keep alive throughout the session.
Thanks in advance.
I don't think the Claim object should be Spring-managed. It's really not injected; sounds like it should be bound from the request sent into the controller and passed to the service for processing. If you put a Claim into session scope, you need to invalidate the session when the transaction is done or if the session times out.
By the way, I see you mention three controllers, but no service. You should have a service layer, and controllers should not deal with DAOs or persistence.
You can change the scope of a bean. Default is singleton which is sometimes not appropriate in web contexts. You can change it to be session scoped by adding for example
the attribute scope="session"
and the child <aop:scoped-proxy proxy-target-class="false"/>
to the bean definition.
I am working with 3.0M4, btw, but I would expect it to be in earlier versions, as well, as it's a very important functionality. Have a look at:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch03s05.html
Cheers!