I have a problem with Hibernate when updating certain data in a table.
If I generate a new record, it is recorded successfully in the table. But if what I want to do is perform an update of the primary key, I throw the following error if the scope of the managed bean is "RequestScoped": "Batch update returned unexpected row count from update [0]; current row count: 0; expected: 1"
If the scope of the managed bean is "ViewScoped", the error is as follows: "Could not extract ResultSet".
If what I modify is another data, the record is recorded satisfactorily.
I understand that it can be a permissions problem to modify the primary key, since this is in turn a foreign key from another table, but this last table does not contain records yet. If from the pgAdmin I change a primary key, I can do it without any problem, therefore it is not a referential integrity problem.
This puzzles me a lot.
I add POJO code:
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
/**
* Combustibles generated by hbm2java
*/
public class Combustibles implements java.io.Serializable {
private int idcombustible;
private String descripcion;
private boolean baja;
private Date fechabaja;
private Set valeses = new HashSet(0);
public Combustibles() {
}
public Combustibles(int idcombustible, String descripcion, boolean baja) {
this.idcombustible = idcombustible;
this.descripcion = descripcion;
this.baja = baja;
}
public Combustibles(int idcombustible, String descripcion, boolean baja, Date fechabaja, Set valeses) {
this.idcombustible = idcombustible;
this.descripcion = descripcion;
this.baja = baja;
this.fechabaja = fechabaja;
this.valeses = valeses;
}
public int getIdcombustible() {
return this.idcombustible;
}
public void setIdcombustible(int idcombustible) {
this.idcombustible = idcombustible;
}
public String getDescripcion() {
return this.descripcion;
}
public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}
public boolean isBaja() {
return this.baja;
}
public void setBaja(boolean baja) {
this.baja = baja;
}
public Date getFechabaja() {
return this.fechabaja;
}
public void setFechabaja(Date fechabaja) {
this.fechabaja = fechabaja;
}
public Set getValeses() {
return this.valeses;
}
public void setValeses(Set valeses) {
this.valeses = valeses;
}
}
Also from the mapping file:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated 24/03/2017 21:42:13 by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
<class name="Pojos.Combustibles" table="combustibles" schema="public" optimistic-lock="version">
<id name="idcombustible" type="int">
<column name="idcombustible" />
<generator class="assigned" />
</id>
<property name="descripcion" type="string">
<column name="descripcion" not-null="true" />
</property>
<property name="baja" type="boolean">
<column name="baja" not-null="true" />
</property>
<property name="fechabaja" type="time">
<column name="fechabaja" length="15" />
</property>
<set name="valeses" table="vales" inverse="true" lazy="true" fetch="select">
<key>
<column name="idcombustible" not-null="true" />
</key>
<one-to-many class="Pojos.Vales" />
</set>
</class>
</hibernate-mapping>
I add the code of the Managed Bean, inside which is the method called modifyCombustible (), which is in charge of the update.
package ManagedBeansRequest;
import Daos.DaoCombustibles;
import HibernateUtil.HibernateUtil;
import Pojos.Combustibles;
import java.util.List;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import org.hibernate.Session;
import org.hibernate.Transaction;
/**
*
* @author Gustavo
*/
@Named(value = "mbCombustibles")
@RequestScoped
public class MbCombustibles {
private Combustibles combustible;
private List<Combustibles> listaCombustibles;
private Session sesion;
private Transaction transaccion;
/**
* Creates a new instance of MbCombustibles
*/
public MbCombustibles() {
this.combustible = new Combustibles();
}
public void registrar() throws Exception{
//Antes era public String, pero se cambió a "void" ya que en la vista se cambió el "action" que requiere una cadena, por "actionListener"
this.sesion = null;
this.transaccion = null;
try{
this.sesion = HibernateUtil.getSessionFactory().openSession();
this.transaccion = this.sesion.beginTransaction();
DaoCombustibles daoC = new DaoCombustibles();
daoC.registrar(this.sesion, this.combustible);
this.transaccion.commit();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Registro","Se registró satisfactoriamente el combustible"));
//RequestContext.getCurrentInstance().execute("limpiarFormulario('frmRegistrarCombustible')");
this.combustible = new Combustibles(); //Esto reemplaza a la función javascript de borrado de campos del formulario, debido a que al instanciar un nuevo objeto, viene con sus atributos limpios
//return "/combustibles/combustiblealta"; //Se reemplaza el return, ya que en la vista se cambió el "action" que requiere una cadena, por "actionListener"
}catch(Exception e){
if(this.transaccion != null){
this.transaccion.rollback();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ocurrió un error","Descripcion: " + e.getMessage()));
}
return; //Se reemplaza el return "null", ya que en la vista se cambió el "action" que requiere una cadena, por "actionListener"
}
finally{
if(sesion != null){
sesion.close();
}
}
}
public List<Combustibles> getTodos(){
this.sesion = null;
this.transaccion = null;
try{
DaoCombustibles daoC = new DaoCombustibles();
this.sesion = HibernateUtil.getSessionFactory().openSession();
this.transaccion = this.sesion.beginTransaction();
this.listaCombustibles = daoC.verTodos(this.sesion);
this.transaccion.commit();
return listaCombustibles;
}catch(Exception e){
if(this.transaccion != null){
this.transaccion.rollback();
}
return null;
}finally{
if(this.sesion != null){
this.sesion.close();
}
}
}
public void modificarCombustible() throws Exception{
//Antes era public String, pero se cambió a "void" ya que en la vista se cambió el "action" que requiere una cadena, por "actionListener"
this.sesion = null;
this.transaccion = null;
try{
this.sesion = HibernateUtil.getSessionFactory().openSession();
this.transaccion = this.sesion.beginTransaction();
DaoCombustibles daoC = new DaoCombustibles();
daoC.modificar(this.sesion, this.combustible);
this.transaccion.commit();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Registro","Se guardaron satisfactoriamente los cambios"));
//RequestContext.getCurrentInstance().execute("limpiarFormulario('frmRegistrarCombustible')");
//this.combustible = new Combustibles(); //Esto reemplaza a la función javascript de borrado de campos del formulario, debido a que al instanciar un nuevo objeto, viene con sus atributos limpios
//return "/combustibles/combustiblealta"; //Se reemplaza el return, ya que en la vista se cambió el "action" que requiere una cadena, por "actionListener"
}catch(Exception e){
if(this.transaccion != null){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ocurrió un error","Descripcion: " + e.getMessage()));
this.transaccion.rollback();
}
}
finally{
if(sesion != null){
sesion.close();
}
}
}
public Combustibles getCombustible() {
return combustible;
}
public void setCombustible(Combustibles combustible) {
this.combustible = combustible;
}
public List<Combustibles> getListaCombustibles() {
return listaCombustibles;
}
public void setListaCombustibles(List<Combustibles> listaCombustibles) {
this.listaCombustibles = listaCombustibles;
}
}
For clarity I also add the code portion of the view from where I called the dialog of PrimeFaces, and the complete code of the dialog:
<p:column>
<p:commandButton value="Editar" oncomplete="PF('dialogoEditarCombustible').show()" update=":frmEditarCombustible">
<f:setPropertyActionListener target="#{mbCombustibles.combustible}" value="#{fila}"/>
</p:commandButton>
</p:column>
<h:form id="frmEditarCombustible">
<p:dialog header="Editar Combustible" widgetVar="dialogoEditarCombustible" modal="true" resizable="false" width="900" showEffect="explode" hideEffect="explode" >
<p:panelGrid id="editarCombustible" columns="3">
<p:outputLabel value="Identificador de Combustible:" for="txtIdentificador"/>
<p:inputText id="txtIdentificador" label="Identificador" value="#{mbCombustibles.combustible.idcombustible}">
<f:validator validatorId="validadorVacio"/>
</p:inputText>
<p:message for="txtIdentificador"/>
<p:outputLabel value="Nombre de combustible:" for="txtDescripcion"/>
<p:inputText id="txtDescripcion" label="Nombre" value="#{mbCombustibles.combustible.descripcion}">
<f:validator validatorId="validadorVacio"/>
</p:inputText>
<p:message for="txtDescripcion"/>
<p:commandButton value="Confirmar Edición" actionListener="#{mbCombustibles.modificarCombustible()}" update=":frmListaCombustibles,editarCombustible"/>
</p:panelGrid>
</p:dialog>
</h:form>