Hibernate - C3P0 - connectionPool - 交易

时间:2013-06-04 14:14:31

标签: java hibernate glassfish-3 connection-pooling c3p0

我正在使用Netbeans 7.3创建一个Web应用程序,使用Primefaces 3.5和Hibernate 3.2.5创建JSF 2.1。我在glassfish服务器3.1.2上运行它 我的项目有一些维护(我不确定如何用英语调用它,我说的是一个可以创建,更新和删除数据的屏幕),如下所示:

(我将一些原始名称和文本从西班牙语改为英语)

MANOPINIONES VIEW:

  <f:view locale="#{sesion.idiomaActual}">
    <h:head>
        <link href="CSS/estilos.css" rel="stylesheet" type="text/css"/>            
    </h:head>
    <h:body rendered="#{sesion.isLogadoAdm()}">
        <h:form>
            <div class="area_mantenimiento">  
                <br/>                
                <p:panel id="panelopi" header="Mantenimiento de opiniones" styleClass="panel_mantenimiento_opi"> 

                        <p:messages globalOnly="true"/>
                        <br/>
                        <p:toolbar>
                            <p:toolbarGroup align="left">  
                               <p:commandButton title="Ok" icon="ui-icon-check" disabled="#{Manopiniones_BackingBean.disabled_ok}" actionListener="#{Manopiniones_BackingBean.saveChangesListener(event)}" update="panelopi"/>  
                               <p:commandButton title="Cancel" icon="ui-icon-closethick"  disabled="#{Manopiniones_BackingBean.disabled_cancel}" actionListener="#{Manopiniones_BackingBean.cancelChangesListener(event)}" update="panelopi"/>                         
                               <p:commandButton title="Delete" icon="ui-icon-circle-minus" type="button" disabled="#{Manopiniones_BackingBean.disabled_del}" onclick="vardialogoopi.show();"/>                                      
                            </p:toolbarGroup>
                        </p:toolbar>
                        <br/><br/>

                        <p:panel>
                            <p:panelGrid columns="3" styleClass="rejilla_panel_login" style="margin:0 0 0 0;font: 10px Verdana;">
                                <h:outputText value="Codigo de opinion:" style="font-weight:bold;"/>
                                <p:inputText value="#{Manopiniones_BackingBean.codigo}" disabled="#{Manopiniones_BackingBean.disabled_cod}" />
                                <p:commandButton title="Buscar" value="&nbsp;" icon="ui-icon-search" disabled="#{Manopiniones_BackingBean.disabled_bot}" actionListener="#{Manopiniones_BackingBean.getOpinionListener(event)}" update="panelopi"/>
                            </p:panelGrid>
                        </p:panel>

                        <p:separator style="width:580px;height:10px; margin:10px auto auto 0;"  />

                        <br/>
                        <p:panel>
                            <p:panelGrid columns="2" styleClass="rejilla_panel_login" style="margin:0 0 0 0;font: 10px Verdana;">
                                <h:outputText value="Texto: " style="font-weight:bold;"/>                       
                                <p:editor value="#{Manopiniones_BackingBean.opinion_actual.opiDes}" maxlength="5000" height="150" width="450" disabled="#{Manopiniones_BackingBean.disabled_opi}"/>                                                

                                <h:outputText value="" />  
                                <h:outputText value="" />  


                            </p:panelGrid>                    
                        </p:panel>

                        <p:confirmDialog message="¿Are you sure to delete this?" header="Confirmacion" severity="alert" widgetVar="vardialogoopi" >
                            <p:commandButton value="OK" actionListener="#{Manopiniones_BackingBean.deleteOpinionListener(event)}" update="panelopi" oncomplete="vardialogoopi.hide();" />
                            <p:commandButton value="Cancel" type="button" onclick="vardialogoopi.hide();"  />
                        </p:confirmDialog> 

                </p:panel> 
            </div>         
        </h:form>
    </h:body>
  </f:view>

MANOPINIONES BACKING BEAN:

@ManagedBean
@ViewScoped
public class Manopiniones_BackingBean {

    private Session sesion=null;
    private Opiniones opinion_actual;
    private Boolean disabled_ok=true;
    private Boolean disabled_cancel=true;    
    private Boolean disabled_del=true;
    private Boolean disabled_cod=false;        
    private Boolean disabled_bot=false;
    private Boolean disabled_opi=true;

    private String codigo="";


    public Manopiniones_BackingBean() {

    }

    @PreDestroy
    public void parar() {    
        if(sesion!=null && sesion.isOpen()){
            sesion.getTransaction().rollback();
            sesion.close();
            opinion_actual=new Opiniones();
            disabled_ok=true;
            disabled_cancel=true;    
            disabled_del=true;
            disabled_cod=false;
            disabled_bot=false;
            disabled_opi=true;
        }
    }  
    public Session getSesion() {
        return sesion;
    }

//GETTER & SETTERS OMITTED

 public void saveChangesListener(ActionEvent event) {  

      try { 
        if(opinion_actual!=null && !codigo.isEmpty()){
            opinion_actual.setOpiCod(codigo);
            sesion.saveOrUpdate(opinion_actual);
            sesion.getTransaction().commit(); 
            sesion.close();
            opinion_actual=new Opiniones();
            disabled_ok=true;
            disabled_cancel=true;    
            disabled_del=true;
            disabled_cod=false;
            disabled_bot=false;
            disabled_opi=true;
        };                                       
    }
     catch (HibernateException he) {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error saving opinion.", null));
        sesion.getTransaction().rollback();
        sesion.close();
        };
} 

public void cancelChangesListener(ActionEvent event) {
        sesion.getTransaction().rollback();
        sesion.close();
        opinion_actual=new Opiniones();
        disabled_ok=true;
        disabled_cancel=true;    
        disabled_del=true;
        disabled_cod=false;
        disabled_bot=false;
        disabled_opi=true;
}

public void deleteOpinionListener(ActionEvent event) {
    try {      
        sesion.delete(opinion_actual);
        sesion.getTransaction().commit(); 
        sesion.close(); 
        opinion_actual=new Opiniones();
        codigo="";
        disabled_ok=true;
        disabled_cancel=true;    
        disabled_del=true;
        disabled_cod=false;
        disabled_bot=false;
        disabled_opi=true;
     }
     catch (HibernateException he) {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error deleting opinion.", null));
        sesion.getTransaction().rollback();
        sesion.close();
        };
}

public void getOpinionListener(ActionEvent event) {              

   try {   
       if(!codigo.isEmpty()){         
            sesion=HibernateUtil.getSessionFactory().openSession(); 
            sesion.beginTransaction();            
            opinion_actual=(Opiniones)sesion.get(Opiniones.class, codigo); 
            disabled_ok=false;
            disabled_cancel=false;                
            disabled_cod=true;
            disabled_bot=true;
            disabled_opi=false;
            disabled_del=false; 
            if(opinion_actual==null){
                opinion_actual=new Opiniones();
                disabled_del=true;                             
            };            
       };        
    }
     catch (HibernateException he) {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error getting opinion.", null));
        sesion.getTransaction().rollback();
        sesion.close();
        };     
}         
}

正如您所看到的,它是一个非常简单的“保养”示例,并且原始配置完美无缺。

我想使用c3p0库实现连接池以提高速度,所以我在hibernate.cfg.xml上添加了这些行

hibernate.cfg.xml中:

<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/agencia</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">THE_PASSWORD</property>   
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
    <property name="hibernate.current_session_context_class">thread</property>
    <property name="hibernate.jdbc.batch_size">50</property>


    **<!-- ADDED LINES TO IMPLEMENT CONNECTION POOL -->** 
    <property name="hibernate.c3p0.min_size">8</property>
    <property name="hibernate.c3p0.max_size">32</property>
    <property name="hibernate.c3p0.timeout">300</property>
    <property name="hibernate.c3p0.max_statements">50</property>
    <property name="hibernate.c3p0.idle_test_period">300</property>
    <property name="hibernate.c3p0.acquire_increment">1</property>        

    <property name="hibernate.connection.datasource">jdbc/PoolAgencia</property>
    **<!-- ADDED LINES TO IMPLEMENT CONNECTION POOL -->**

    **<!-- HIBERNATE MAPPING OMITTED -->**

  </session-factory>
</hibernate-configuration>

我还在glassfish服务器上创建了一个连接池。 我下载并将mysql-connector-java-5.0.8-bin添加到我的服务器。为了配置池,我刚刚更改了这些可选属性:

Databasename = the_database_name

Password = the_password

Portnumber = 3306

Servername = localhost

User = root

最后我创建了一个名为jdbc/PoolAgencia的JDBC资源。

它似乎运作良好,数据在网络的其他点非常快速地检索。然后我用这种方式使用 upkeep

  • 我进入了“维护”页面。

  • 我介绍了一个代码

  • 我按了“搜索”按钮。

  • 然后我按下“取消”按钮,我收到此错误:

SEVERE: JDBC rollback failed
com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Can't call rollback when autocommit=true
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:888)
at com.mysql.jdbc.Connection.rollback(Connection.java:5257)
at com.sun.gjc.spi.base.ConnectionHolder.rollback(ConnectionHolder.java:630)
at org.hibernate.transaction.JDBCTransaction.rollbackAndResetAutoCommit(JDBCTransaction.java:183)
at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:162)

如果我以这种方式使用“保养”:

  • 我去了“维修”页面。
  • 我介绍了一个代码(它不介意它是新代码还是现有代码)
  • 我按下“搜索”按钮。(如果代码存在于数据库中,则会检索它,否则会创建新代码)
  • 然后我按下“确定”按钮(应保存所有更改),我收到此错误:
SEVERE: JDBC commit failed
java.sql.SQLException: Can't call commit when autocommit=true
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:914)
at com.mysql.jdbc.Connection.commit(Connection.java:2275)
at com.sun.gjc.spi.base.ConnectionHolder.commit(ConnectionHolder.java:244)
at org.hibernate.transaction.JDBCTransaction.commitAndResetAutoCommit(JDBCTransaction.java:139)

当我读到这两个错误时,我理解交易在池中无法正常工作。我认为这是连接池或hibernate配置问题。我已经在网上进行了搜索,我试图改变连接池的一些配置选项而没有运气。

为什么会这样?

1 个答案:

答案 0 :(得分:2)

尝试在hibernate配置中将autocommit模式设置为false

<property name="connection.autocommit">false</property>