问题
I am trying to upload a file (picture) which is part of a Product
object to a database. The file upload is successful according to the jsf confirmation. However, when persisting Product
the persistence is completed successfully without the picture. The server is not returning any stack.
This is my form (simplified):
<h:form enctype="multipart/form-data">
<h1><h:outputText value="Create New Product"/></h1>
<h:panelGrid columns="2">
<h:outputLabel value="Name:" for="name" />
<h:inputText id="name" value="#{productController.product.name}" title="Name" />
<h:outputLabel value="Description:" for="description" />
<h:inputText id="description" value="#{productController.product.description}" title="Description" />
<h:outputLabel value="Price:" for="price" />
<h:inputText id="price" value="#{productController.product.price}" title="Price" />
<h:outputLabel value="Category:" for="category_fk" />
<h:selectOneMenu id="category_fk" value="#{productController.product.category_fk}"
converter="#{categoryConverter}" title="Category_fk" >
<f:selectItems value="#{productController.categoryList}" var="prodCat"
itemValue="#{prodCat}" itemLabel="#{prodCat.name}"/>
</h:selectOneMenu>
<p:fileUpload fileUploadListener="#{productController.handleFileUpload}" update="msg" auto="true" />
<p:growl id="msg" showDetail="true"/>
<h:inputHidden id="dateAdded" value="#{productController.product.dateAdded}">
<f:convertDateTime pattern="yyyy/MM/dd HH:mm:ss" />
</h:inputHidden>
</h:panelGrid>
<h:commandButton value="Create Product" action="#{productController.doCreateProduct()}"/>
</h:form>
This the product Controller (Simplified):
@ManagedBean
@RequestScoped
public class ProductController {
@EJB
private ProductEJB productEjb;
@EJB
private CategoryEJB categoryEjb;
private Product product = new Product();
private List<Product> productList = new ArrayList<Product>();
private Category category;
private List<Category> categoryList = new ArrayList<Category>();
// -------------------------------------------------------- Business Methods
public String doCreateProduct()
{
product = productEjb.createProduct(product);
productList = productEjb.findAllProducts();
return "listProduct?faces-redirect=true";
}
public String doDeleteProduct()
{
productEjb.deleteProduct(product);
return "listProduct?faces-redirect=true";
}
public String cancelDeleteAction()
{
return "listProduct?faces-redirect=true";
}
// Update product listing
public void preRenderView()
{
if(product == null)
{
product = new Product();
}
}
public String doUpdateProduct()
{
if(product.getProduct_id() != 0)
{
productEjb.updateProduct(product);
}
else
{
productEjb.createProduct(product);
}
//addFlashMessage("Product " + product.getName() + " (" + product.getProduct_id() + ") has been updated");
return "listProduct?faces-redirect=true";
}
public void handleFileUpload(FileUploadEvent event)
{
byte[] uploadedFile = new byte[event.getFile().getContents().length];
System.arraycopy(event.getFile().getContents(), 0, uploadedFile, 0, event.getFile().getContents().length);
product.setImageFile(uploadedFile);
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + "is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
@PostConstruct
public void init()
{
categoryList = categoryEjb.findAllCategory();
productList = productEjb.findAllProducts();
}
This is the product entity(Simplified):
@Entity
@NamedQueries({
@NamedQuery(name="findAllProducts", query = "SELECT p from Product p")
})
public class Product implements Serializable
{
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy= GenerationType.AUTO)
private int product_id;
private String name;
private String description;
@Lob
@Column(name="imageFile")
protected byte[] imageFile;
private Float price;
@Temporal(TemporalType.TIMESTAMP)
private Date dateAdded;
@ManyToOne
private Category category_fk;
@OneToOne(mappedBy = "product_fk")
private SaleDetails saleDetails_fk;
SOLUTION: I changed the scope of the managed bean to:
@ViewScope
回答1:
Fileupload happens in a first request.
When form is submited with the input data, a new 2nd request will be initiated. A new requestScoped ManagedBean will be created, that doesnt know about the previous fileupload.
To allow the two requests to share the same Managedbean, Change the scope to:
@ViewScoped
来源:https://stackoverflow.com/questions/13410555/primefaces-fails-to-upload-file-to-db