Send Object between #ViewScoped beans - jsf

I managed to create very simple example of sending Object between JSF pages:
First page:
#Named
#ViewScoped
public class Pricing
{
public Pricing()
{
int ww = 3;
PricingFormData obj = new PricingFormData(334, "Lalalala");
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("yourKey", obj);
}
Second page:
#Named
#ViewScoped
public class PricingCalculator implements Serializable
{
PricingFormData get;
public PricingCalculator()
{
get = (PricingFormData) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("yourKey");
}
}
Custom Object:
public class PricingFormData
{
private int id;
private String name;
public PricingFormData(int id, String name)
{
this.id = id;
this.name = name;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
This code works but I have several questions which I want to ask:
The code is working in View scope. What will happen if multiple users are clicking on the pages? Are these Objects are going to be mixed? Do I need to use some unique ID for Object key for example session ID. But here I don't have session.
What will happen if the Objects are too many(multiple users are working on the web site)? When the objects will be disposed?

Related

JSF-Managed Beans and Design Patterns [duplicate]

This question already has answers here:
JSF Controller, Service and DAO
(2 answers)
Closed 6 years ago.
Lets assume, i have a student.xhtml form that has radiolists&dropdownmenu populated from its #ManagedBean Student(). As u know, in order to populate form from managedbean i need to have List<Object> fields in Student class. But i also want my Student class to be pure meaning it should have fields only related to itself, not the possible values it can get (i mean List<>). So i want to seperate my Student class from #ManagedBean. So i will have two classes at the end one of is pure Student class and StudentBean class which controls the view.
So my question is, is it good practice have two classes like below or i should go with one class? Two classes method duplicates fields so i don't know whether it affects performance to a bad extent.. What do you suggest?
Not wanted BeanClassWithStudent Pattern;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.*;
#ManagedBean
public class Student {
private String firstName;
private String lastName;
private String country;
private String favLanguage;
private List<String> countryList;
private List<String> favLanguageList;
#PostConstruct // generate DropDownList Combobox and radiobuttons From class fields
public void init() {
generateCountries();
generateFavLanguages();
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getFavLanguage() {
return favLanguage;
}
public void setFavLanguage(String favLanguage) {
this.favLanguage = favLanguage;
}
public List<String> getCountryList() {
return countryList;
}
public List<String> getFavLanguageList() {
return favLanguageList;
}
private void generateCountries(){
countryList = new ArrayList<>();
countryList.add("Turkey");
countryList.add("France");
countryList.add("Senegal");
countryList.add("USA");
}
private void generateFavLanguages(){
favLanguageList = new ArrayList<>();
favLanguageList.add("Java");
favLanguageList.add("Ruby");
favLanguageList.add("C++");
favLanguageList.add("Visual Basic");
}
}
My wanted seperate classes;
Student.class
public class Student {
private String firstName;
private String lastName;
private String country;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
Wanted StudentControllerBean;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.*;
#ManagedBean
public class StudentBean {
private String firstName;
private String lastName;
private String country;
private List<String> countryList;
private List<String> favLanguageList;
#PostConstruct // generate DropDownList Combobox and radiobuttons From class fields
public void init() {
generateCountries();
generateFavLanguages();
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public List<String> getCountryList() {
return countryList;
}
public List<String> getFavLanguageList() {
return favLanguageList;
}
private void generateCountries(){
countryList = new ArrayList<>();
countryList.add("Turkey");
countryList.add("France");
countryList.add("Senegal");
countryList.add("USA");
}
private void generateFavLanguages(){
favLanguageList = new ArrayList<>();
favLanguageList.add("Java");
favLanguageList.add("Ruby");
favLanguageList.add("C++");
favLanguageList.add("Visual Basic");
}
}
It is always better to maintain two separate Beans one for the presentation layer (#ManagedBean) and the other one (called as Business/Entiry Bean) for the Business tier (services layer) i.e., it is not a good idea to mix up both the presentation tier (Managed) beans with the Business beans rather you need to separate them like how you did.
The request flow between the J2EE tiers goes as follows:
HTML/JSP -> ManagedBean -> Service -> DAO -> Database
You need to convert the presentation bean data to the Business bean in the Action classes and then pass that to Business Bean Object to the Services layer. Service layer uses this Business Bean to interact with DAO classes which persist or do some transactions with the database.
This concept is applicable not only for JSF, but all other J2EE web frameworks (like Struts, Spring MVC, etc..).
You can find more details here on this concept.

spring-data-cassandra component/complex type denormalized mapping

I'm trying to use spring-data-cassandra (1.1.2.RELEASE) and I'm running into an issue with the lack of embeddable type mapping in JPA parlance.
I have an entity class like this:
#Table
public class Customer {
private UUID id;
private String name;
private Address address;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
and the embeddable Address class:
public class Address {
private String address;
private String city;
private String state;
private String zip;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
}
My cassandra table:
create table customer (
id uuid primary key,
name text,
address text,
city text,
state text,
zip text
);
I want the properties of Address to be mapped into the containing entity, I don't want a separate table for addresses. In JPA, I believe I'd use an #Embeddable annotation. Is there some similar construct in spring-data-cassandra?
Embeddable types are not yet supported by spring-data-cassandra. A feature request is available at DATACASS-167.
The only possible part of an entity to embed is the primary key. If your primary key consists of multiple fields, you can externalize that fields into a separate class and use it afterwards with the #PrimaryKey annotation.
Comment.java
#Table("comments")
public class Comment {
#PrimaryKey
private CommentKey pk;
private String text;
}
CommentKey.java
#PrimaryKeyClass
public class CommentKey implements Serializable {
private static final long serialVersionUID = -7871651389236401141L;
#PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED)
private String author;
#PrimaryKeyColumn(ordinal = 1)
private String company;
}
HTH, Mark

groovy not recognizing java getters/setters through field syntax

I have the following inheritance hierarchy defined in java.
public class BaseModel extends HashMap<String, Object> {
public String getString(String key) {
return (String)this.getOrDefault(key, "EMPTY");
}
}
public class Entity extends BaseModel {
private String id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Now in a groovy script I try to do the following:
Entity entity = new Entity();
entity.id = "101";
entity.name = "Apple"
and "id" and "name" are not recognized. The funny thing is they are recognized if I do one of the following:
not inherit Entity from BaseModel
Rather than inherit BaseModel from HashMap, make HashMap a data member of BaseModel
inherit Entity directly from HashMap
At first I thought that groovy is not recognizing the "id" and "name" syntax because of extending HashMap, but #3 above proves that incorrect. I am stumped as to why this is not being recognized at this point. Can someone help me out? It should be easy enough to copy paste this and try it out yourself.
The problem seems to be the setters and getters inside the Entity Class, everything in groovy is public and it creates all the getters and setters methods.
I tested the next code in the groovy console and it worked.
public class BaseModel extends HashMap<String, Object> {
public String getString(String key) {
return (String)this.getOrDefault(key, "EMPTY");
}
}
public class Entity extends BaseModel {
private String id;
private String name;
}
Entity entity = new Entity();
entity.id = "101";
entity.name = "Apple"
println entity.id
It prints 101 in the groovyConsole output screen.
When Entity is extending from BaseModel or directly a HashMap, Entity becomes a Map. So, when we say entity.id, Groovy is trying to find an entry in the map whose key is 'id'. As there is no such entry, it prints out null.
public class Entity extends HashMap<String, String> {
private String id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Entity entity = new Entity();
entity.id = "101";
entity.name = "Apple"
println entity.id //prints null
But when Entity is not extending from BaseModel anymore, entity.id will be interpreted just as a member of Entity.
public class Entity {
private String id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Entity entity = new Entity();
entity.id = "101";
entity.name = "Apple"
println entity.id //prints 101

Serialize HashMap like a Collection Property

Here I got two classes "Student" and "Course":
#XmlRootElement
class Student {
private String name;
private HashMap<String, Course> courses;
public Student() {}
public Student(String name, HashMap<String, Course> courses) {
super();
this.name = name;
this.courses = courses;
}
// -------------------------getters
#XmlAttribute(name="name")
public String getName() {
return name;
}
#XmlElement(name = "course")
public HashMap<String, Course> getCourses() {
return courses;
}
//---------------------------setters
public void setName(String name) {
this.name = name;
}
public void setCourses(HashMap<String, Course> courses) {
this.courses = courses;
}
}
#XmlRootElement
class Course {
private String id;
private String name;
public Course() {}
public Course(String id, String name) {
super();
this.id = id;
this.name = name;
}
#XmlID
#XmlAttribute(name = "id")
public String getId() {
return id;
}
#XmlAttribute(name = "name")
public String getName() {
return name;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
I want to serialize the Student class using JaxB annotations to something like the following:
<Student name="David">
<courses>
<Course id="1" name="Fundamentals of Programming"/>
<Course id="2" name="Advanced Programming">
</courses>
</Student>
Note that I want courses field of the Student to be HashMap and when unmarshalling the serialized Object use id as the key for each Course.
You can use an XmlAdapter for this use case. An XmlAdapter allows you to programmatically convert an object to another type for the purpose of marshalling/unmarshalling. For your use case you will convert the HashMap to an instance of an object that has a collection of Course.
http://blog.bdoughan.com/2010/07/xmladapter-jaxbs-secret-weapon.html

backing bean in jsf scope

I am displaying a ProductList, which is made up of Product objects. The Product has attributes of type int, string, string, and int. The data is being pulled from the database and I build a ProductList. The data is in the database, I can see it, but when I display the table, the table shows 0's for the 2 int columns, and blanks in the String columns. Here is the ProductList:
#ManagedBean
public class ProductList {
private ArrayList<Product> allProducts;
public ProductList(){
allProducts = DatabaseConnector.getAllProducts();
}
public ArrayList<Product> getAllProducts(){
return allProducts;
}
public void setAllProducts(ArrayList<Product> allProducts){
this.allProducts = allProducts;
}
}
And here is the Product bean:
#ManagedBean
public class Product {
private int id;
private String productName;
private String description;
private int quantity;
public Product() {
}
public void setId(int id) {
this.id = id;
}
public void setProductName(String productName) {
this.productName = productName;
}
public void setDescription(String description) {
this.description = description;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getId() {
return id;
}
public String getProductName() {
return productName;
}
public String getDescription() {
return description;
}
public int getQuantity() {
return quantity;
}
}
Should I change the scope of the beans?
Add scope annotation to your bean , for example #RequestScoped or #ViewScoped
otherwise it will be the default scope which is #NoneScoped

Resources