I display images stored in BLOB form in MySQL on <p:graphicImage> as follows.
<p:dataTable var="row" value="#{testManagedBean}" lazy="true" editable="true" rows="10"> <p:column headerText="id"> <h:outputText value="#{row.brandId}"/> </p:column> <p:column headerText="Image"> <p:cellEditor> <f:facet name="output"> <p:graphicImage value="#{brandBean.image}" height="100" width="100"> <f:param name="id" value="#{row.brandId}"/> </p:graphicImage> </f:facet> <f:facet name="input"> <p:graphicImage id="image" value="#{brandBean.image}" height="100" width="100"> <f:param name="id" value="#{row.brandId}"/> </p:graphicImage> </f:facet> </p:cellEditor> </p:column> <p:column headerText="Edit" width="50"> <p:rowEditor/> </p:column> </p:dataTable>
When editing a line on <p:overlayPanel> , the symbol <p:fileUpload> . This and many other things are omitted in this example for simplicity, since they are not related to a specific problem.
JSF related bean:
@ManagedBean @ViewScoped public final class TestManagedBean extends LazyDataModel<Brand> implements Serializable { @EJB private final TestBeanLocal service=null; private static final long serialVersionUID = 1L; @Override public List<Brand> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) { setRowCount(3); return service.getList(); } }
a bean that retrieves images from a database based on a unique row identifier - BrandBean .
@ManagedBean @ApplicationScoped public final class BrandBean { @EJB private final BrandBeanLocal service=null; public BrandBean() {} public StreamedContent getImage() throws IOException { FacesContext context = FacesContext.getCurrentInstance(); if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) { return new DefaultStreamedContent(); } else { String id = context.getExternalContext().getRequestParameterMap().get("id"); System.out.println("id = "+id); byte[] bytes = service.findImageById(Long.parseLong(id)); return bytes==null? new DefaultStreamedContent(new ByteArrayInputStream(new byte[0])):new DefaultStreamedContent(new ByteArrayInputStream(bytes)); } } }
When a row is updated (after editing it) by clicking on the <p:rowEditor> located (indicated by <p:rowEditor> ) in the last column of the data table, the getImage() method in BrandBean is called as it should.
This happens correctly in an application running on a GlassFish 4.0 server using PrimeFaces 5.0 and JSF 2.2.6.
The new image will be displayed in the data table immediately after updating the row in the data table (and therefore in the database).
There is another application on the Tomcat 8.0.5 server that uses Spring 4.0.0 GA, in which the getImage() method getImage() not called after updating the row stored in the data table, resulting in still displaying the old image (and not the updated one) in the data table ( even if the changes are correctly transferred to the database).
The updated image is displayed only when you refresh the page by pressing F5 (in most browsers). It does not even appear when the page loads (entering the URL into the address bar, and then pressing the enter key).
In other words, when a row in the data table is updated by clicking on the tick specified by <p:rowEditor> , the getImage() method getImage() not called (therefore, the new image is not retrieved from the database displayed on <p:graphicImage> ). This method is called only when the page is refreshed / reloaded by pressing the F5 key.
Why is this happening? How to show a recently updated image immediately after updating a row?
Superficially, this should not be connected with Spring and JPA (the update operation correctly spreads to the database after clicking on the checkmark). Rather, it should be related to the Tomcat server.