How to set a list for addEntry with PostConstruct - jsf

Until now I add the things I want to have in my list over the getter which makes no sense and end in a mess up in my database, when adding a new entry.
My model until now:
#Data
#Entity
public class Telefonbuch {
/*#PostConstruct
public void init() {
//geschaeftsstellen = new ArrayList<String>();
geschaeftsstellen.add("Dortmund");
System.out.println("TEEEEEEEEEEEST");
geschaeftsstellen.add("Essen");
geschaeftsstellen.add("Stralsund");
geschaeftsstellen.add("Stuttgart");
geschaeftsstellen.add("Zürich");
geschaeftsstellen.add("Istanbul");
geschaeftsstellen.add("Köln");
geschaeftsstellen.add("Aachen");
geschaeftsstellen.add("Berlin");
}*/
public List<String> getGeschaeftsstellen() {
geschaeftsstellen = new ArrayList<String>();
geschaeftsstellen.add("Dortmund");
System.out.println("TEEEEEEEEEEEST");
geschaeftsstellen.add("Essen");
geschaeftsstellen.add("Stralsund");
geschaeftsstellen.add("Stuttgart");
geschaeftsstellen.add("Zürich");
geschaeftsstellen.add("Istanbul");
geschaeftsstellen.add("Köln");
geschaeftsstellen.add("Aachen");
geschaeftsstellen.add("Berlin");
//ArrayList<String> a = new ArrayList<String>();
//a.add("Test");
return geschaeftsstellen;
}
public void setGeschaeftsstellen(List<String> geschaeftsstellen) {
this.geschaeftsstellen = geschaeftsstellen;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column
private String vorname;
#Column
private String nachname;
#Column
private String telefonnummer;
#Column
private String handynummer;
#Column
private String geschaeftsstelle;
#Column
#ElementCollection
private List<String> geschaeftsstellen;
I just show the other variables to let you know what is in this. I know the #Column annotation for the List is not necessary. But it's a question for me. Should data like this be in a database or not? I will never use it again somewhere else. What is the right way to insert the data of the list for these selection buttons? When I just uncomment the PostConstruct it won't get called.
When I add #ManagedBean I get the error: DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.
But in my .xhtml I already have selection="#{telefonbuchList.selectedEntry}" selectionMode="single" rowKey="#{telefonbuch.id}"
How do i know which import is the right one? javax.annotation or javax.faces.bean? Just with the annotation one it gets called.
Here can see where I use it. It's the tab "Neuer Eintrag" for a newEntry. The tab "Telefonbuch" is the list with a table for all entities.
Edit:
TelefonbuchListController on Request:
#Scope (value = "session")
#Component (value = "telefonbuchList")
#ELBeanName(value = "telefonbuchList")
#Join(path = "/", to = "/eintraege-liste.jsf")
public class TelefonbuchListController {
#Autowired
private TelefonbuchRepository telefonbuchRepository;
private List<Telefonbuch> eintraege;
#Deferred
#RequestAction
#IgnorePostback
public void loadData() {
eintraege = telefonbuchRepository.findAll();
}
public List<Telefonbuch> getEintraege() {
return eintraege;
}
private Telefonbuch selectedEntry;
public Telefonbuch getSelectedEntry() {
return selectedEntry;
}
public void setSelectedEntry(Telefonbuch selectedEntry) {
this.selectedEntry = selectedEntry;
}
public void deleteEntry() {
telefonbuchRepository.delete(selectedEntry);
eintraege.remove(selectedEntry);
selectedEntry = null;
}

I got your question that you are asking for a List getting filled with options usable with a selectOneRadio component - and why #PostConstruct does not work. #PostConstruct is ignored by JPA or other persistence frameworks - it's usable with CDI/Managed beans as far as I know.
Move it to your TelefonbuchList bean:
public class TelefonbuchListController {
#PostConstruct
public void init() {
geschaeftsstellen = new ArrayList<String>();
geschaeftsstellen.add("Dortmund");
geschaeftsstellen.add("Essen");
...
}
public List<String> getGeschaeftsstellen() {
return geschaeftsstellen;
}
}
You can use this list to fill your selectOneRadio component select items.

Related

Convert List of Objects to List of Strings

I'm using Spring data jpa findAll() method. So it returns List of objects.
here is the entity.
#Entity
#Table(name = "country")
#Data
public class CountryEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "country_id")
private Long id;
#Column(name = "country_name")
private String name;
#OneToMany(mappedBy ="countryEntity")
private Collection<GovernmentEntity> governments;
}
and data jpa findAll() method is
List<CountryEntity> entities = countryRepo.findAll();
I want to get list of Country names as String WITHOUT USING loops or streams (performance issues).
I used streams and it works fine with javaFx ListView
#FxmlView("/address.fxml")
#Component
#RequiredArgsConstructor
public class HomeController implements Initializable {
private ObservableList<String> countriesNames;
#FXML
private ListView<String> countryListView;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
List<CountryEntity> entities = countryRepo.findAll();
List <String> countryList = entities.stream().map(o-> Objects.toString(o.getName())).collect(Collectors.toList());
countriesNames = FXCollections.observableList(countryList);
countryListView.getItems().addAll(countriesNames);
}
}
Make your ListView a ListView<CountryEntity>, and use a cell factory to customize the display:
public class HomeController implements Initializable {
private ObservableList<String> countriesNames;
#FXML
private ListView<CountryEntity> countryListView;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
List<CountryEntity> entities = countryRepo.findAll();
countryListView.getItems().addAll(entities);
countryListView.setCellFactory(lv -> new ListCell<CountryEntity>() {
#Override
protected void updateItem(CountryEntity country, boolean empty) {
super.updateItem(country, empty);
if (empty || country == null) {
setText("");
} else {
setText(country.getName()); // or however you want to display it
}
});
}
}
If you genuinely only want a list of country names, and don't want to retrieve a list of CountryEntitys and extract the names from them, then you need to define a method in your repository for the purpose:
public interface CountryEntityRepository extends JpaRepository<CountryEntity, Long> {
// existing methods...
#Query("select c.name from CountryEntity c")
List<String> findCountryNames() ;
}
And then of course just do
#FXML
private ListView<String> countryListView ;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
countryListView.getItems().addAll(countryRepo.findCountryNames());
}
However, the first approach is almost certainly preferred. You will likely need the other data in the CountryEntity at some point.

Why is my Primefaces.current() returning null

So, I have this page:
#Named("ManagementPage")
#ViewScoped
#Getter
#Setter
#Join(path = "/{appScope}/admin/management",
to = "/pages/scoped/managementOverview.xhtml")
#Page(
group = "kitchen",
icon = "mdi mdi-comment-text",
key = "management",
navigation = Page.Navigation.ADMIN_SCOPED,
outcome = "/pages/scoped/managementOverview.xhtml",
auth = #PageAuth(value = "MANAGER_ACCESS", scoped = true))
public class ManagementPage implements Serializable {
private static final long serialVersionUID = 1L;
#Inject
private ManagementModel model;
#PostConstruct
public void init() {
this.model.init();
}
}
It's ViewScoped. And the model for it is:
#Log4j
#Dependent
#Getter
#Setter
public class ManagementModel implements Serializable {
...
}
I want, whenever I receive an event, to refresh some UI on the frontend (I'm using JSF). For that, I've created this dispatcher:
#ApplicationScoped
public class OrderEventDispatcher {
private static final List<ManagementModel> subscriptions = new ArrayList<>();
public static void addSubscriber(ManagementModel subscriber) {
subscriptions.add(subscriber);
}
public static void removeSubscriber(ManagementModel subscriber) {
subscriptions.remove(subscriber);
}
public void observerOrderCreated(#Observes FrontendEvent frontendEvent) {
if(frontendEvent instanceof ContentItemCreatedEvent){
if(!"order".equals(((ContentItemCreatedEvent) frontendEvent).getTypeKey())){
return;
}
}
if(frontendEvent instanceof ContentItemChangedEvent){
if(!"order".equals(((ContentItemChangedEvent) frontendEvent).getTypeKey())){
return;
}
}
subscriptions.forEach(ManagementModel::orderInit);
}
}
(I have implemented a proper equals for this in my model)
For my dispatcher to work, I'm subcribing with my model to it (the methods are inside the model)
#PostConstruct
public void init() {
id = totalIds++;
OrderEventDispatcher.addSubscriber(this);
...
And then i unsubscribe before I destroy the model:
#PreDestroy
public void preDestroy() {
OrderEventDispatcher.removeSubscriber(this);
}
And finally, the methods I call from my dispatcher:
public void orderInit() {
loadMergedOrders();
initializeDonut();
PrimeFaces.current().executeScript("orderInit()");
}
I'm doing all this in order to refresh my page (even when multiple instance of the same page are open) in reaction to an event (some item is created/deleted/modified, of that the FrontendEvent takes care). Now the issue is that my PrimeFaces.current() is always returning null, I've added a breakpoint in the init() method and I tried using PrimeFaces.current() and it worked then, but then when I went through the Dispatcher and into the orderInit() with the debugger I've seen that PrimeFaces.current() now returns null. Does anyone have any idea what I'm doing wrong? If not how to fix this then maybe a different approach to solving this. Thanks for your time!

Set value to ManagedProperty

I'm trying to set a value to my ManagedProperty but I'm getting the null result when I try to print this.
I'd like to set the Bean Class to use it in my query.
I've been tryin' set String, Class, but all the times it returned a null value.
Can anyone help me?
#ManagedBean
public class FilialBean extends BaseBean implements Serializable{
private Filial filial;
private List<Filial> filiais;
#ManagedProperty("#{entidadeService}")
private EntidadeService service;
#PostConstruct
public void init(){
service.setFaces(Filial.class);
filial = new Filial();
filiais = (List<Filial>) (List) service.getbasesEntidades();
}
//GETTERS AND SETTERS
}
#ManagedBean(name="entidadeService", eager=true)
#ApplicationScoped
public class EntidadeService implements Serializable{
private List<EntidadeBase> basesEntidades;
private Class faces;
#PostConstruct
public void init(){
System.out.println(faces.getSimpleName());
try{
EntityManager manager = JPAUtil.getEntityManager();
Query query = manager.createQuery("SELECT e FROM Filial e WHERE e.ativo = :ativo");
query.setParameter("ativo", true);
this.basesEntidades = query.getResultList();
}
catch(Exception e){
e.printStackTrace();
}
}
public List<EntidadeBase> getbasesEntidades() {
return basesEntidades;
}
public Class getFaces() {
return faces;
}
public void setFaces(Class faces) {
this.faces = faces;
}
}
Have you check that #ManagedBean has same package in both classes?
I ran into same problem, a property with null value executing Post Construct method and this is the problem, one class had javax.annotation.ManagedBean (CDI) annotation and the other had javax.faces.bean.ManagedBean (JSF) annotation.
In my case I needed both classes with JSF annotations...

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.

p:dataTable single selection radio button error : cannot be cast to java.util.Collection

Primefaces 4.0
Hello, I'm trying to implement a <p:dataTable> with radio button single selection. The table is rendered right, but when U submit the page I get the following error:
java.lang.ClassCastException: [Lpt.ef.besa.pe.common.api.TermDepositProduct; cannot be cast to java.util.Collection
at org.primefaces.component.datatable.DataTable.getRowData(DataTable.java:977)
at org.primefaces.component.datatable.feature.SelectionFeature.decodeSingleSelection(SelectionFeature.java:47)
at org.primefaces.component.datatable.feature.SelectionFeature.decode(SelectionFeature.java:38)
at org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:60)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:787)
at org.primefaces.component.api.UIData.processDecodes(UIData.java:232)
at javax.faces.component.UIForm.processDecodes(UIForm.java:225)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
My Datatable code:
<p:dataTable var="product" value="#{availableTermDepositProducts.rows}" selection="#{form.product}"
emptyMessage="#{i18n['messages.global.dataTable.emptyMessage']}" rowKey="#{product.id}">
<p:column selectionMode="single" />
...columns
</p:dataTable>'
My backing bean:
public class TermDepositProductSubscriptionFormBean implements Serializable {
private static final long serialVersionUID = 1L;
private TermDepositProduct product;
private String productId;
private boolean automaticRenewal;
private boolean interestCapitalization;
private BigDecimal amount;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public boolean isAutomaticRenewal() {
return automaticRenewal;
}
public void setAutomaticRenewal(boolean automaticRenewal) {
this.automaticRenewal = automaticRenewal;
}
public boolean isInterestCapitalization() {
return interestCapitalization;
}
public void setInterestCapitalization(boolean interestCapitalization) {
this.interestCapitalization = interestCapitalization;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public TermDepositProduct getProduct() {
return product;
}
public void setProduct(TermDepositProduct product) {
this.product = product;
}
}
Why does it keep trying to cast to a collection if im using single selection?
-Thanks
Datatable Selection with Array is currently not supported, so im gonna fill the datatable with a collection.
I though Primefaces was trying to cast the Selected Item to a collection, instead it was trying to cast the Array i used to fill the datatable, hence the error. I wasnt reading the error log with attention.

Resources