Primefaces picklist. Setter for DualListModel removes source and target - jsf

I am having a problem with my picklist. Showing the source and targets works, but when the commandbutton is pressed it calles the setter of the picklist and empties the source and target of the picklist. After that it calls the method connectTags().
What is the reason of this behavior and how could I solve this?
<h:form>
<p:pickList id="pickList" value="#{employeeEditController.dualListTags}"
var="tag" itemLabel="#{tag.value}" itemValue="#{tag}">
<f:facet name="sourceCaption">Available</f:facet>
<f:facet name="targetCaption">Connected</f:facet>
</p:pickList>
<p:commandButton value="Save" actionListener="#{employeeEditController.connectTag()}"/>
</h:form>
Bean:
#Named(value = "employeeEditController")
#SessionScoped
public class EmployeeEditController implements Serializable, IEditController {
private Employee selectedEmployee;
private DualListModel<Tags> dualListTags;
#Inject
private EmployeeFacade employeeFacade;
#Inject
private CompanyFacade companyFacade;
#Inject
private TagFacade tagFacade;
public void setSelectedEmployee(Employee selectedEmployee) {
System.out.println("setSelectedEmployee called. Value: " + selectedEmployee.getFirstName());
this.selectedEmployee = selectedEmployee;
this.refreshDualList();
}
private void refreshDualList(){
List<Tags> source = (List<Tags>) this.getCompanyTags();
List<Tags> target = (List<Tags>) this.getTags();
System.out.println("refreshDualList called. \nSource: " + source.size() +
"Target: " + target.size());
this.dualListTags = new DualListModel<Tags>(source, target);
}
public Collection<Tags> getTags(){
Collection<Tags> retVal;
if(this.selectedEmployee != null){
retVal = this.selectedEmployee.getTags();
if(retVal == null){
retVal = new ArrayList<Tags>();
}
} else{
System.out.println("selected emp is null");
retVal = new ArrayList<Tags>();
}
return retVal;
}
public Collection<Tags> getCompanyTags() {
Collection<Tags> retVal = new ArrayList<Tags>();
if(this.companyID == null){
String userstr = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
this.companyID = this.companyFacade.getCompanyIDByUser(userstr);
}
retVal = this.tagFacade.getTagsFromCompanyID(companyID);
return retVal;
}
public void save(){
if(this.selectedEmployee != null){
System.out.println("Save called. Value: " + this.selectedEmployee.getFirstName());
this.employeeFacade.edit(this.selectedEmployee);
}
}
public void connectTag() {
if(this.dualListTags != null){
System.out.println("connectTag() called.\n" + "source: " + this.dualListTags.getSource().size() +
"\ntarget: " + this.dualListTags.getTarget().size());
this.selectedEmployee.setTags((Collection<Tags>)this.dualListTags.getTarget());
this.save();
}
}
public DualListModel<Tags> getDualListTags() {
System.out.println("getDualList called. \nSource :" + this.dualListTags.getSource().size()
+ "\nTargets: " + this.dualListTags.getTarget().size());
return this.dualListTags;
}
public void setDualListTags(DualListModel<Tags> dualListTags) {
System.out.println("setDualList called. \nSource :" + this.dualListTags.getSource().size()
+ "\nTargets: " + this.dualListTags.getTarget().size());
this.dualListTags = dualListTags;
System.out.println("setDualList called after set. \nSource :" + this.dualListTags.getSource().size()
+ "\nTargets: " + this.dualListTags.getTarget().size());
}
}

I had the same problem and it seems that the solution is to impement a custom converter for the entity you use in picklist.
This is how my custom converter looks like:
#ViewScoped
#ManagedBean(name = "vehicleGroupConverter")
public class VehicleGroupConverter implements Converter {
#ManagedProperty(value = "#{vehiclesBean}")
private VehiclesBean vehiclesBean;
#Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
long groupId = Long.parseLong(value);
List<AssetCategory> groups = vehiclesBean.getVehicleGroups();
for (AssetCategory group : groups) {
if (group.getCategoryId() == groupId) {
return group;
}
}
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
return Long.toString(((AssetCategory) value).getCategoryId());
}
public void setVehiclesBean(VehiclesBean vehiclesBean) {
this.vehiclesBean = vehiclesBean;
}
}
And this is the picklist template part:
<p:pickList id="vehicleGroups"
value="#{vehiclesBean.selectedVehicleGroups}"
var="group"
itemLabel="#{group.name}"
itemValue="#{group}"
converter="#{vehicleGroupConverter}"
styleClass="pf-panel-grid"
style="margin-bottom:10px">
<f:facet name="sourceCaption">#{i18n['label-available-groups']}</f:facet>
<f:facet name="targetCaption">#{i18n['label-assigned-groups']}</f:facet>
</p:pickList>

Sets duallistmodel when source or target not empty:
public void setDualListTags(DualListModel<Tags> dualListTags) {
if(this.dualListTags.getSource().size()!=0 && this.dualListTags.getTarget().size()!=0) {
this.dualListTags = dualListTags;
}
}

Related

Get composite component inputs' converted values

I have a composite component made of two p:calendars:
<cc:interface componentType="testComponent">
<cc:attribute name="value" type="org.primefaces.test.DateRange" />
</cc:interface>
<cc:implementation>
<c:set value="dd-MM-yyyy" var="pattern" />
<p:panelGrid columns="2">
<p:outputLabel for="from" value="From" />
<p:calendar id="from" binding="#{cc.from}" pattern="#{pattern}" />
<p:outputLabel for="to" value="To" />
<p:calendar id="to" binding="#{cc.to}" pattern="#{pattern}" />
</p:panelGrid>
</cc:implementation>
Class DateRange:
public class DateRange {
private Date from;
private Date to;
public DateRange() {
}
public DateRange(Date from, Date to) {
this.from = from;
this.to = to;
}
public Date getFrom() {
return from;
}
public void setFrom(Date from) {
this.from = from;
}
public Date getTo() {
return to;
}
public void setTo(Date to) {
this.to = to;
}
#Override
public String toString() {
return from + " --> " + to;
}
}
Backing class:
#FacesComponent("testComponent")
public class TestComponent extends UIInput implements NamingContainer {
private UIInput from;
private UIInput to;
private static final String DELIMITER = "-->";
#Override
public String getFamily() {
return UINamingContainer.COMPONENT_FAMILY;
}
#Override
public void encodeBegin(FacesContext context) throws IOException {
DateRange range = (DateRange) getValue();
System.out.println(range);
if (range != null) {
from.setValue(range.getFrom());
to.setValue(range.getTo());
}
super.encodeBegin(context);
}
#Override
public Object getSubmittedValue() {
if (from == null || to == null) return null;
String submittedFrom = (String) from.getSubmittedValue();
String submittedTo = (String) to.getSubmittedValue();
if (submittedFrom == null) {
submittedFrom = "";
}
if (submittedTo == null) {
submittedTo = "";
}
return submittedFrom + DELIMITER + submittedTo;
}
#Override
protected Object getConvertedValue(FacesContext context, Object newSubmittedValue) throws ConverterException {
String submitted = (String) newSubmittedValue;
if (submitted == null || submitted.isEmpty()) {
return null;
}
String[] split = submitted.split(DELIMITER);
String fromStr = split.length > 0 ? split[0] : "";
String toStr = split.length > 1 ? split[1] : "";
// TODO: Do I need to perform a manual conversion of the inputs???
return new DateRange((Date) fromObj, (Date) toObj);
}
getConvertedValue() should return an instance of DateRange. To get dates from calendars, I would need to call getConvertedValue() on each but this method is protected and I cannot access it.
Do I need to manually get the pattern from the p:calendar and convert the value myself? If yes, how do I even know how the conversion is really done in Calendaritself? I wonder how is this approached in more complex components where conversion on subcomponents is not that trivial.

PrimeFaces auto complete return a null object

this is my xhtml page
<h:form id="order_search" prependId="flase">
<p:growl id="growl" showDetail="true" autoUpdate="true"
sticky="false" />
<h:panelGrid columns="5" style="margin-bottom:10px" cellpadding="5">
<p:outputLabel value="Customer Name : " for="ac_order" />
<p:autoComplete id="ac_order" value="#{orderSearchController.orderFromAutoC}"
completeMethod="#{orderSearchController.autoCompleteOrder}" var="order"
itemLabel="#{order.customerName}" itemValue="#{order}"
converter="#{orderConverter}" forceSelection="true" />
<p:commandButton id="selected" value="print" action="#{orderSearchController.printOrder}" />
</h:panelGrid>
</h:form>
and this is my backing bean
#Component
#ManagedBean
#ViewScoped
public class OrderSearchController implements Serializable{
private static final long serialVersionUID = 1L;
#ManagedProperty(value = "#{orderService}")
public OrderService orderService;
public List<Order> allOrders;
public List<Order> acFilterdOrders;
public Order orderFromAutoC;
#PostConstruct
public void Init() {
System.out.println("init gets called");
// allOrders = new ArrayList<>();
// orderFromAutoC = new Order();
allOrders = orderService.getAllOrders();
System.out.println("After sssssss ");
}
public List<Order> autoCompleteOrder(String query) {
acFilterdOrders = new ArrayList<Order>();
for (int i = 0; i < allOrders.size(); i++) {
if (allOrders.get(i).getCustomerName().toLowerCase().startsWith(query)) {
acFilterdOrders.add(allOrders.get(i));
}
}
return acFilterdOrders;
}
public String printOrder() {
System.out.println("Inside print");
System.out.println("Inside print : "+orderFromAutoC);
return null;
}
//Getters and Setters
}
and this is my converter code
#ManagedBean(name = "orderConverter")
#RequestScoped
public class OrderConverter implements Converter {
#ManagedProperty(value = "#{orderService}")
private OrderService orderService;
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String value) {
if (value != null && value.trim().length() > 0) {
return orderService.getOrderById(Integer.parseInt(value));
} else {
return null;
}
}
#Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
// TODO Auto-generated method stub
return null;
}
public OrderService getOrderService() {
return orderService;
}
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
}
the auto-complete component works fine but but when i tried to get the selected value from it in the backing bean it always return a null
The getAsString method is not implemented correctly as it is just returning the NULL value. The return value of getAsString method is passed as value in the getAsObject method based on which it get the value from the list. Here is an example for your reference . Value in the getAsObject method is the Id that is returned from getAsString method.
#Override
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if(value != null && value.trim().length() > 0) {
MessageLogBean messageLogBean = (MessageLogBean) SessionUtility.getManagedBean("messageLogBean");
DeviceResponseDTO deviceResponseDTO = new DeviceResponseDTO();
deviceResponseDTO.setId(Integer.parseInt(value));
List<DeviceResponseDTO> deviceResponseDTOs = messageLogBean.getDeviceResponseDTOs();
int index = deviceResponseDTOs.indexOf(deviceResponseDTO);
if(null != deviceResponseDTOs && !deviceResponseDTOs.isEmpty()){
return deviceResponseDTOs.get(index);
}
return null;
}
else {
return null;
}
}
#Override
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
if(object != null) {
return String.valueOf(((DeviceResponseDTO) object).getId());
}
else {
return null;
}
}

Catching PrimeFaces's spinner value inside repeat structure

I'm using Primefaces and spinner component. My problem is that the spinner value is not set in the bean, if it's inside an iteration structure. My spinner is inside ui:repeat.
In the end, the problem is how to deal with different form controls mapping to the same property in bean.
<h:form>
<ui:repeat var="item" value="#{myBean.items}">
<p:spinner size="2" min="1" max="50" style="width:75px" value="#{cartBean.quantityToOrder}"/>
<p:commandButton value="Add to cart" action="#{cartBean.saveItemToCart(item)}" ajax="false"/>
</ui:repeat>
</h:form>
and my bean
#ManagedBean
#SessionScoped
public class CartBean extends BaseBean {
private int quantityToOrder;
//setter, getter...
//When called quantityToOrder = 0 always
public void saveItemToOrder(Item item) {
quantityToOrder IS 0.
}
}
I suspect it has to do with form submission, I have tried a form enclosing all elements in the collection and also a form enclosing any of the spinners + button. The generated client IDs are distinct for all spinners.
Any help would be appreciated.
Put a System.out.println("quantity: " + quantityToOrder) on your setQuantityToOrder(int quantityToOrder) method and will will see the problem. The value of the last spinner will prevail over the others because all the spinners are pointed to the same property (cartBean.quantityToOrder).
Try moving the quantityToOrder to the Item as follows:
<h:form id="mainForm">
<ui:repeat value="#{cartBean.items}" var="item">
<p:outputLabel value="#{item.name}: " for="sp" />
<p:spinner id="sp" size="2" min="1" max="50" style="width:75px" value="#{item.quantityToOrder}" />
<p:commandButton value="Add to cart" action="#{cartBean.saveItemToOrder(item)}" process="#this, sp" update=":mainForm:total" />
<br />
</ui:repeat>
Total: <h:outputText id="total" value="#{cartBean.quantityToOrder}" />
</h:form>
The cartBean:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class CartBean implements Serializable {
private List<CartItem> items;
private int quantityToOrder;
#PostConstruct
public void setup() {
items = new ArrayList<CartItem>();
items.add(new CartItem(1, "A"));
items.add(new CartItem(2, "B"));
items.add(new CartItem(3, "C"));
}
public void saveItemToOrder(CartItem item) {
//do whatever you want to do with the item quantity.
System.out.println("Qtd of " + item.getName() + ": " + item.getQuantityToOrder());
//to calculte the qtd of items on the cart.
quantityToOrder = 0;
for (CartItem cartItem : items) {
quantityToOrder += cartItem.getQuantityToOrder();
}
}
public List<CartItem> getItems() {
return items;
}
public void setItems(List<CartItem> items) {
this.items = items;
}
public int getQuantityToOrder() {
return quantityToOrder;
}
public void setQuantityToOrder(int quantityToOrder) {
this.quantityToOrder = quantityToOrder;
}
}
The CartItem:
import java.io.Serializable;
public class CartItem implements Serializable {
private Integer id;
private Integer quantityToOrder;
private String name;
public CartItem(Integer id, String name) {
this.id = id;
this.name = name;
quantityToOrder = 0;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getQuantityToOrder() {
return quantityToOrder;
}
public void setQuantityToOrder(Integer quantityToOrder) {
this.quantityToOrder = quantityToOrder;
}
#Override
public int hashCode() {
int hash = 7;
hash = 67 * hash + (this.id != null ? this.id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CartItem other = (CartItem) obj;
if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
return false;
}
return true;
}
}

reloading jsf datatable generated using CRUD on clicking a command button

my jsf page
<h:form>
<h:dataTable id="btable" value="#{ballController.items}" var="item">
<h:column>
<h:outputText value="#{item.id}"/>
</h:column>
<h:column>
<h:outputText value="#{item.bname}"/>
</h:column>
</h:dataTable>
<h:commandButton action="#{ballCOntroller.items}" value="test">
<f:ajax execute="#form" render="btable" />
</h:commandButton>
</h:form>
in my controller, this method is called by ballController.items
public DataModel getItems() {
if (items == null) {
items = getPagination().createPageDataModel();
}
return items;
}
but upon clicking the button itl give me an error saying:
serverError: classjavax.faces.el.MethodNotFoundException
/app/ball/index.xhtml #40,101 action="#{ballController.items}": Method
not found: ballController#a7150b6.items()
my goal is to reload the dataTable on clicking the command button without refreshing the entire page.
*Edited
my whole bean code
#ManagedBean(name = "ballController")
#ViewScoped
public class ballController implements Serializable {
private ball current;
private DataModel items = null;
#EJB
private ballFacade ejbFacade;
private PaginationHelper pagination;
private int selectedItemIndex;
public ballController() {
}
public ball getSelected() {
if (current == null) {
current = new ball();
selectedItemIndex = -1;
}
return current;
}
private ballFacade getFacade() {
return ejbFacade;
}
public PaginationHelper getPagination() {
if (pagination == null) {
pagination = new PaginationHelper(10) {
#Override
public int getItemsCount() {
return getFacade().count();
}
#Override
public DataModel createPageDataModel() {
return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
}
};
}
return pagination;
}
public String prepareList() {
recreateModel();
return "List";
}
public String prepareView() {
current = (ball) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
return "View";
}
public String prepareCreate() {
current = new ball();
selectedItemIndex = -1;
return "index";
}
public String create() {
try {
getFacade().create(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ballCreated"));
return prepareCreate();
// return null;
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
return null;
}
}
public String prepareEdit() {
current = (ball) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
return "Edit";
}
public String update() {
try {
getFacade().edit(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ballUpdated"));
return "View";
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
return null;
}
}
public String destroy() {
current = (ball) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
performDestroy();
recreatePagination();
recreateModel();
return "List";
}
public String destroyAndView() {
performDestroy();
recreateModel();
updateCurrentItem();
if (selectedItemIndex >= 0) {
return "View";
} else {
// all items were removed - go back to list
recreateModel();
return "List";
}
}
private void performDestroy() {
try {
getFacade().remove(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ballDeleted"));
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
}
}
private void updateCurrentItem() {
int count = getFacade().count();
if (selectedItemIndex >= count) {
// selected index cannot be bigger than number of items:
selectedItemIndex = count - 1;
// go to previous page if last page disappeared:
if (pagination.getPageFirstItem() >= count) {
pagination.previousPage();
}
}
if (selectedItemIndex >= 0) {
current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
}
}
public DataModel getItems() {
if (items == null) {
items = getPagination().createPageDataModel();
}
return items;
}
private void recreateModel() {
items = null;
}
private void recreatePagination() {
pagination = null;
}
public String next() {
getPagination().nextPage();
recreateModel();
return "List";
}
public String previous() {
getPagination().previousPage();
recreateModel();
return "List";
}
public SelectItem[] getItemsAvailableSelectMany() {
return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
}
public SelectItem[] getItemsAvailableSelectOne() {
return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
}
#FacesConverter(forClass = ball.class)
public static class ballControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
ballController controller = (ballController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "ballController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Integer getKey(String value) {
java.lang.Integer key;
key = Integer.valueOf(value);
return key;
}
String getStringKey(java.lang.Integer value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof ball) {
ball o = (ball) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + ball.class.getName());
}
}
}
}
To reload the table , you just need to use <f:ajax render="btable" />
<h:commandButton value="test">
<f:ajax render="btable" />
</h:commandButton>
But to to do some action , like adding some data to table you need to point the button to a a proper method
<h:commandButton value="test" action="#{ballController.addItem}"">
<f:ajax render="btable" />
</h:commandButton>
public void addItem() {
if (items == null) {
items = getPagination().createPageDataModel();
}
items.getWrappedData().add(/*something like new MyObject("one","two")*/);
}
serverError: classjavax.faces.el.MethodNotFoundException /app/ball/index.xhtml #40,101 action="#{ballController.items}": Method not found: ballController#a7150b6.items()
Is occurring because you are trying to access getItems in an incorrect way.
Update your bean code as:
public DataModel items() {
if (items == null) {
items = getPagination().createPageDataModel();
}
return items;
}
or else change your facelet action EL expression as action="#{ballCOntroller.getItems}".
EDIT
You can update your List as:
public class DataTableBean implements Serializable {
List<String> dataModelList = new ArrayList<DataModel>();
public List<DataModel> getDataModelList() {
return dataTableList;
}
public void setDataModelList(List<String> dataModelList) {
this.dataTableList = dataTableList;
}
public void addItems(){
List<DataModel> tempList = getPagination().createPageDataModel(); // Returns a list of type `List<DataModel>`.
dataModelList.addAll(tempList);
}
}

How can we enable many to many relationship through a JSF page using Netbeans?

Used a simple InnoDB MySQL database (many to many relationship between WRITER and FORUM, and a join table named writer_forum) in Netbeans 7.1 and created a Java EE 6 web application running under Glassfish 3.1 Open Source Edition. No Other frameworks are being used except JSF 2.0
Generated Entities from Database (using EclipseLink (JPA 2.0) and everything seems fine, the code in the entities is correct as far as I can tell.
Generated JSF pages from Entities (the IDE generates EJB Session beans, Managed Beans and JSF pages using facelets .xhtml).
ALl relationships are supported except MANY TO MANY.
Does anyone had the same experience and managed to enable Many to Many relationship support?
package entities;
#Entity
#Table(name = "writer")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Writer.findAll", query = "SELECT w FROM Writer w"),
#NamedQuery(name = "Writer.findByWriterid", query = "SELECT w FROM Writer w WHERE w.writerid = :writerid"),
#NamedQuery(name = "Writer.findByName", query = "SELECT w FROM Writer w WHERE w.name = :name"),
#NamedQuery(name = "Writer.findBySurname", query = "SELECT w FROM Writer w WHERE w.surname = :surname"),
#NamedQuery(name = "Writer.findByField", query = "SELECT w FROM Writer w WHERE w.field = :field")})
public class Writer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#NotNull
#Column(name = "writerid")
private Integer writerid;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 45)
#Column(name = "name")
private String name;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 45)
#Column(name = "surname")
private String surname;
#Size(max = 45)
#Column(name = "field")
private String field;
#ManyToMany(mappedBy = "writerCollection")
private Collection<Forum> forumCollection;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "writer")
private Collection<Book> bookCollection;
public Writer() {
}
public Writer(Integer writerid) {
this.writerid = writerid;
}
public Writer(Integer writerid, String name, String surname) {
this.writerid = writerid;
this.name = name;
this.surname = surname;
}
public Integer getWriterid() {
return writerid;
}
public void setWriterid(Integer writerid) {
this.writerid = writerid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
#XmlTransient
public Collection<Forum> getForumCollection() {
return forumCollection;
}
public void setForumCollection(Collection<Forum> forumCollection) {
this.forumCollection = forumCollection;
}
#XmlTransient
public Collection<Book> getBookCollection() {
return bookCollection;
}
public void setBookCollection(Collection<Book> bookCollection) {
this.bookCollection = bookCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (writerid != null ? writerid.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Writer)) {
return false;
}
Writer other = (Writer) object;
if ((this.writerid == null && other.writerid != null) || (this.writerid != null && !this.writerid.equals(other.writerid))) {
return false;
}
return true;
}
#Override
public String toString() {
return name + " | " + writerid;
}
}
-------- FORUM JPA entity
#Entity
#Table(name = "forum")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Forum.findAll", query = "SELECT f FROM Forum f"),
#NamedQuery(name = "Forum.findByForumid", query = "SELECT f FROM Forum f WHERE f.forumid = :forumid"),
#NamedQuery(name = "Forum.findByLabel", query = "SELECT f FROM Forum f WHERE f.label = :label")})
public class Forum implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#NotNull
#Column(name = "forumid")
private Integer forumid;
#Size(max = 45)
#Column(name = "label")
private String label;
#JoinTable(name = "forum_writer", joinColumns = {
#JoinColumn(name = "forum_forumid", referencedColumnName = "forumid")}, inverseJoinColumns = {
#JoinColumn(name = "writer_writerid", referencedColumnName = "writerid")})
#ManyToMany
private Collection<Writer> writerCollection;
public Forum() {
}
public Forum(Integer forumid) {
this.forumid = forumid;
}
public Integer getForumid() {
return forumid;
}
public void setForumid(Integer forumid) {
this.forumid = forumid;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
#XmlTransient
public Collection<Writer> getWriterCollection() {
return writerCollection;
}
public void setWriterCollection(Collection<Writer> writerCollection) {
this.writerCollection = writerCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (forumid != null ? forumid.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Forum)) {
return false;
}
Forum other = (Forum) object;
if ((this.forumid == null && other.forumid != null) || (this.forumid != null && !this.forumid.equals(other.forumid))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entities.Forum[ forumid=" + forumid + " ]";
}
}
Asbtract Facade
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
public List<T> findAll() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return getEntityManager().createQuery(cq).getResultList();
}
public List<T> findRange(int[] range) {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
javax.persistence.Query q = getEntityManager().createQuery(cq);
q.setMaxResults(range[1] - range[0]);
q.setFirstResult(range[0]);
return q.getResultList();
}
public int count() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
cq.select(getEntityManager().getCriteriaBuilder().count(rt));
javax.persistence.Query q = getEntityManager().createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
}
}
Forum Facade
#Stateless
public class ForumFacade extends AbstractFacade<Forum> {
#PersistenceContext(unitName = "writerPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public ForumFacade() {
super(Forum.class);
}
}
------------- Managed Bean
#ManagedBean(name = "writerController")
#SessionScoped
public class WriterController implements Serializable {
private Writer current;
private DataModel items = null;
#EJB
private session.WriterFacade ejbFacade;
private PaginationHelper pagination;
private int selectedItemIndex;
public WriterController() {
}
public Writer getSelected() {
if (current == null) {
current = new Writer();
selectedItemIndex = -1;
}
return current;
}
private WriterFacade getFacade() {
return ejbFacade;
}
public PaginationHelper getPagination() {
if (pagination == null) {
pagination = new PaginationHelper(10) {
#Override
public int getItemsCount() {
return getFacade().count();
}
#Override
public DataModel createPageDataModel() {
return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
}
};
}
return pagination;
}
public String prepareList() {
recreateModel();
return "List";
}
public String prepareView() {
current = (Writer) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
return "View";
}
public String prepareCreate() {
current = new Writer();
selectedItemIndex = -1;
return "Create";
}
public String create() {
try {
getFacade().create(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("WriterCreated"));
return prepareCreate();
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
return null;
}
}
public String prepareEdit() {
current = (Writer) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
return "Edit";
}
public String update() {
try {
getFacade().edit(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("WriterUpdated"));
return "View";
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
return null;
}
}
public String destroy() {
current = (Writer) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
performDestroy();
recreatePagination();
recreateModel();
return "List";
}
public String destroyAndView() {
performDestroy();
recreateModel();
updateCurrentItem();
if (selectedItemIndex >= 0) {
return "View";
} else {
// all items were removed - go back to list
recreateModel();
return "List";
}
}
private void performDestroy() {
try {
getFacade().remove(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("WriterDeleted"));
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
}
}
private void updateCurrentItem() {
int count = getFacade().count();
if (selectedItemIndex >= count) {
// selected index cannot be bigger than number of items:
selectedItemIndex = count - 1;
// go to previous page if last page disappeared:
if (pagination.getPageFirstItem() >= count) {
pagination.previousPage();
}
}
if (selectedItemIndex >= 0) {
current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
}
}
public DataModel getItems() {
if (items == null) {
items = getPagination().createPageDataModel();
}
return items;
}
private void recreateModel() {
items = null;
}
private void recreatePagination() {
pagination = null;
}
public String next() {
getPagination().nextPage();
recreateModel();
return "List";
}
public String previous() {
getPagination().previousPage();
recreateModel();
return "List";
}
public SelectItem[] getItemsAvailableSelectMany() {
return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
}
public SelectItem[] getItemsAvailableSelectOne() {
return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
}
#FacesConverter(forClass = Writer.class)
public static class WriterControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
WriterController controller = (WriterController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "writerController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Integer getKey(String value) {
java.lang.Integer key;
key = Integer.valueOf(value);
return key;
}
String getStringKey(java.lang.Integer value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Writer) {
Writer o = (Writer) object;
return getStringKey(o.getWriterid());
} else {
throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + WriterController.class.getName());
}
}
}
}
---------- XTMLCreate PAGE for WRITER----
**
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="title">
<h:outputText value="#{bundle.CreateWriterTitle}"></h:outputText>
</ui:define>
<ui:define name="body">
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
</h:panelGroup>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="#{bundle.CreateWriterLabel_writerid}" for="writerid" />
<h:inputText id="writerid" value="#{writerController.selected.writerid}" title="#{bundle.CreateWriterTitle_writerid}" required="true" requiredMessage="#{bundle.CreateWriterRequiredMessage_writerid}"/>
<h:outputLabel value="#{bundle.CreateWriterLabel_name}" for="name" />
<h:inputText id="name" value="#{writerController.selected.name}" title="#{bundle.CreateWriterTitle_name}" required="true" requiredMessage="#{bundle.CreateWriterRequiredMessage_name}"/>
<h:outputLabel value="#{bundle.CreateWriterLabel_surname}" for="surname" />
<h:inputText id="surname" value="#{writerController.selected.surname}" title="#{bundle.CreateWriterTitle_surname}" required="true" requiredMessage="#{bundle.CreateWriterRequiredMessage_surname}"/>
<h:outputLabel value="#{bundle.CreateWriterLabel_field}" for="field" />
<h:inputText id="field" value="#{writerController.selected.field}" title="#{bundle.CreateWriterTitle_field}" />
</h:panelGrid>
<br />
<h:commandLink action="#{writerController.create}" value="#{bundle.CreateWriterSaveLink}" />
<br />
<br />
<h:commandLink action="#{writerController.prepareList}" value="#{bundle.CreateWriterShowAllLink}" immediate="true"/>
<br />
<br />
<h:commandLink value="#{bundle.CreateWriterIndexLink}" action="/index" immediate="true" />
</h:form>
</ui:define>
</ui:composition>
</html>
**
I am not 100% sure but I think, you may not retrieving any results beacuse of #XMLTransiet annotation above the Serie.class method;
#XmlTransient
public Collection<Writer> getWriterCollection() {
return writerCollection;
}
I would also like to review these documents https://docs.oracle.com/javaee/6/api/javax/xml/bind/annotation/XmlTransient.html

Resources