2016-06-09 74 views
0

我使用泽西2开发的Web服务和Hibernate 5.我会解释Hibernate架构。正确架构新泽西WS + Hibernate来并发

我使用DAO模式:只有一个唯一的DAO,尽管我有几类。我还没有创建Dao应该实现的任何接口。我认为前者在架构方面根本不对。这是我道:

public class PtDao{ 

    /* 
    * Atributos 
    */ 
    private static PtDao INSTANCE = null; 

    private Session currentSession; 
    private Transaction currentTransaction; 
    private SessionFactory factory; 

    /* 
    * Métodos 
    */ 
    private PtDao() throws HibernateException, ConfigurationException{ 
     factory = getSessionFactory(); 
    } 

    public static PtDao getInstance() throws HibernateException, ConfigurationException{ 
     if(INSTANCE == null){ 
      INSTANCE = new PtDao(); 
     } 

     return INSTANCE; 
    } 

    public Session openCurrentSession() throws HibernateException { 
     currentSession = factory.openSession(); 
     return currentSession; 
    } 

    public void closeCurrentSession() { 
     currentSession.close(); 
     currentSession = null; 
    } 

    private SessionFactory getSessionFactory() throws HibernateException, ConfigurationException{ 

     if(getFactory() == null){ 
      Configuration cfg = new Configuration(); 

      cfg.setProperty("hibernate.dialect", "org.hibernate.spatial.dialect.postgis.PostgisDialect"); 
      cfg.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver"); 

      PropertiesConfiguration config = PropertiesConfiguration.getInstance(); 

      String strUrl = "jdbc:postgresql://" + config.getDb_host() + ":" + config.getDb_port() + "/" + config.getDb_database(); 

      cfg.setProperty("hibernate.connection.url", strUrl); 
      cfg.setProperty("hibernate.connection.username", config.getDb_user()); 
      cfg.setProperty("hibernate.connection.password", config.getDb_passwd()); 

      cfg.setProperty("hibernate.hbm2ddl.auto", "update"); 
      cfg.setProperty("hibernate.show_sql", "false"); 
      cfg.setProperty("hibernate.format_sql", "false"); 
      cfg.setProperty("hibernate.generate_statistics", "false"); 

      // C3p0 connection pool 
      cfg.setProperty("connection.provider_class", "org.hibernate.connection.C3P0ConnectionProvider"); 
      cfg.setProperty("c3p0.min_size", "7"); 
      cfg.setProperty("c3p0.max_size", "10000"); 
      cfg.setProperty("c3p0.timeout", "1000"); 
      cfg.setProperty("c3p0.idle_test_period", "2000"); 
      cfg.setProperty("c3p0.preferredTestQuery", "select 1;"); 

      cfg.addAnnotatedClass(Tarifa.class); 
      cfg.addAnnotatedClass(Provincia.class); 
      cfg.addAnnotatedClass(Comarca.class); 
      cfg.addAnnotatedClass(Municipio.class); 
      cfg.addAnnotatedClass(Salto.class); 

      StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder() 
        .applySettings(cfg.getProperties()); 
      setFactory(cfg.buildSessionFactory(builder.build())); 

     } 

     return getFactory(); 

    } 

    public Session getCurrentSession() { 
     return currentSession; 
    } 

    public void setCurrentSession(Session currentSession) { 
     this.currentSession = currentSession; 
    } 

    public Transaction getCurrentTransaction() { 
     return currentTransaction; 
    } 

    public void setCurrentTransaction(Transaction currentTransaction) { 
     this.currentTransaction = currentTransaction; 
    } 

    public Transaction beginTransaction(){ 
     this.currentTransaction = currentSession.beginTransaction(); 
     return this.getCurrentTransaction(); 
    } 

    public void commitTransaction(){ 
     if(currentTransaction != null) 
      currentTransaction.commit(); 
    } 

    public void rollbackTransaction(){ 
     if(currentTransaction != null) 
      currentTransaction.rollback(); 
    } 

    public SessionFactory getFactory() { 
     return factory; 
    } 

    public void setFactory(SessionFactory factory) { 
     this.factory = factory; 
    } 

    public void finish() throws HibernateException { 
     Session session = getCurrentSession(); 
     if(session != null) 
      session.close(); 
     if(factory != null) 
      factory.close(); 
    } 


    @SuppressWarnings("unchecked") 
    public List<Municipio> getMunicipios(){ 
     Query q = currentSession.createQuery("from Municipio"); 
     return q.list(); 
    } 

    public Municipio getMunicipioByCoor(Point coor) throws NoExisteMunicipioException{ 
     Criteria crit = currentSession.createCriteria(Municipio.class); 
     crit.add(SpatialRestrictions.contains("geom", coor)); 
     @SuppressWarnings("unchecked") 
     List<Municipio> l = crit.list(); 
     if (l.isEmpty()) 
      throw new NoExisteMunicipioException(coor); 
     return l.get(0); 
    } 

    public Comarca getComarcaById(Integer pIdComarca) throws NoExisteComarcaException{ 
     Criteria crit = currentSession.createCriteria(Comarca.class); 
     crit.add(Restrictions.eq("id", pIdComarca)); 
     crit.setMaxResults(1); 
     @SuppressWarnings("rawtypes") 
     List comarcas = crit.list(); 
     if(comarcas.isEmpty()) 
      throw new NoExisteComarcaException(pIdComarca); 
     return (Comarca) comarcas.get(0); 
    } 

    public Boolean existenSaltosComarcas(){ 
     Criteria crit = currentSession.createCriteria(Salto.class); 
     @SuppressWarnings("rawtypes") 
     List saltos = crit.list(); 
     Boolean tiene = false; 
     if(saltos != null){ 
      if(!saltos.isEmpty()){ 
       tiene = true; 
      } 
     } 
     return tiene; 
    } 

    public void crearSalto(Comarca pComarcaOrigen, Comarca pComarcaDestino, int pNumeroSaltos) { 
     Salto elSalto = new Salto(pComarcaOrigen, pComarcaDestino, pNumeroSaltos); 
     currentSession.save(elSalto); 
    } 

    public Integer getCantidadSaltos(Municipio municipioInicio, Municipio municipioFin) throws SinViajesEntreZonasException { 
     System.out.println("getCantidadSaltos()"); 
     Integer saltos = null; 
     Criteria crit = currentSession.createCriteria(Salto.class); 
     crit.add(
      Restrictions.and(
       Restrictions.eq("origen", municipioInicio.getZona_mugi()), 
       Restrictions.eq("destino", municipioFin.getZona_mugi()) 
      ) 
     ); 
     crit.setMaxResults(1); 
     @SuppressWarnings("rawtypes") 
     List res = crit.list(); 
     if(res != null){ 
      if(!res.isEmpty()){ 
       saltos = ((Salto) res.get(0)).getNumeroSaltos(); 
      }else{ 
       throw new SinViajesEntreZonasException(municipioInicio.getZona_mugi(), municipioFin.getZona_mugi()); 
      } 
     }else{ 
      throw new SinViajesEntreZonasException(municipioInicio.getZona_mugi(), municipioFin.getZona_mugi()); 
     } 
     return saltos; 
    } 

    public Boolean existenTarifas() { 
     Boolean existen = false; 

     Criteria crit = currentSession.createCriteria(Tarifa.class); 
     crit.setProjection(Projections.rowCount()); 
     Long cant = (Long) crit.uniqueResult(); 
     if(cant > 0){ 
      existen = true; 
     } 

     return existen; 
    } 

    public void crearTarifa(Tarifa pTarifa) { 
     currentSession.saveOrUpdate(pTarifa); 
    } 

    public Tarifa getTarifa(TipoTarifa pTipoTarifa) throws NoExisteTarifaException { 
     Criteria crit = currentSession.createCriteria(Tarifa.class); 
     crit.add(Restrictions.idEq(pTipoTarifa)); 

     Tarifa t = (Tarifa) crit.uniqueResult(); 

     if(t == null){ 
      throw new NoExisteTarifaException(pTipoTarifa); 
     }else{ 
      return t; 
     } 

    } 

} 

我有一个服务层,它执行的动作在Web服务端点开始:

public class PtDaoService { 

    private PtDao dao; 

    public PtDaoService() throws HibernateException, ConfigurationException{ 
     dao = PtDao.getInstance(); 
    } 

    public void finish() throws HibernateException { 
     dao.finish(); 
    } 

    public void imprimirZonas(){ 
     try { 
      dao.openCurrentSession(); 
      List<Municipio> municipios = dao.getMunicipios(); 
      for(Municipio m:municipios){ 
       System.out.println(m.toString()); 
      } 
      dao.closeCurrentSession(); 
     } catch (HibernateException e) { 
      System.err.println("Error HibernateException: " + e.getMessage()); 
      e.printStackTrace(); 
     } 
    } 

    public Municipio getMunicipioByCoor(Point coor) throws NoExisteMunicipioException{ 
     try { 
      dao.openCurrentSession(); 
      Municipio municipio = dao.getMunicipioByCoor(coor);   
      dao.closeCurrentSession(); 
      return municipio; 
     } catch (HibernateException e) { 
      System.err.println("Error HibernateException: " + e.getMessage()); 
      e.printStackTrace(); 
      return null; 
     } 
    } 

    public void inicializarTarifasSiNoExisten(){ 
     boolean construyendo = false; 
     try { 
      dao.openCurrentSession(); 
      if(!dao.existenTarifas()){ 
       construyendo = true; 
       dao.beginTransaction(); 
       Tarifa ocasional = new Tarifa(
         TipoTarifa.Ocasional, 
         "Sin condiciones", 
         Money.of(CurrencyUnit.EUR, 1.70), 
         Money.of(CurrencyUnit.EUR, 2.45), 
         Money.of(CurrencyUnit.EUR, 4.65), 
         Money.of(CurrencyUnit.EUR, 6.85), 
         Money.of(CurrencyUnit.EUR, 8.90), 
         Money.of(CurrencyUnit.EUR, 12.00)); 
       dao.crearTarifa(ocasional); 

       Tarifa tramo1 = new Tarifa(
         TipoTarifa.Tramo1, 
         "Descuento del 45%", 
         Money.of(CurrencyUnit.EUR, 0.93), 
         Money.of(CurrencyUnit.EUR, 1.35), 
         Money.of(CurrencyUnit.EUR, 2.56), 
         Money.of(CurrencyUnit.EUR, 3.77), 
         Money.of(CurrencyUnit.EUR, 4.90), 
         Money.of(CurrencyUnit.EUR, 6.60)); 
       dao.crearTarifa(tramo1); 
       dao.commitTransaction(); 
      } 
      dao.closeCurrentSession(); 
     } catch (HibernateException e) { 
      if(construyendo) 
       dao.rollbackTransaction(); 
      System.err.println("Error HibernateException: " + e.getMessage()); 
      e.printStackTrace(); 
     } 
    } 

    public void inicializarSaltosComarcasSiNoExisten(){ 
     //a method 
    } 

    public Integer getCantidadSaltos(Double pOriginLatitude, Double pOriginLongitude, Double pDestinationLatitude, 
      Double pDestinationLongitude) throws SinViajesEntreZonasException, NoExisteMunicipioException, ErrorEnGetCantidadSaltosException { 

     System.out.println("getCantidadSaltos() [ pOriginLatitude=" + pOriginLatitude + ", pOriginLongitude=" + pOriginLongitude + ", pDestinationLatitude=" + pDestinationLatitude + ", pDestinationLongitude=" + pDestinationLongitude + " ]"); 

     Point inicio = GeometriesFactory.createPoint(pOriginLatitude, pOriginLongitude); 
     Point fin = GeometriesFactory.createPoint(pDestinationLatitude, pDestinationLongitude); 

     try { 
      dao.openCurrentSession(); 
      Municipio municipioInicio = dao.getMunicipioByCoor(inicio);   
      Municipio municipioFin = dao.getMunicipioByCoor(fin); 

      Integer saltos = dao.getCantidadSaltos(municipioInicio, municipioFin); 

      dao.closeCurrentSession(); 

      return saltos; 
     } catch (HibernateException e) { 
      System.err.println("Error HibernateException: " + e.getMessage()); 
      e.printStackTrace(); 
      throw new ErrorEnGetCantidadSaltosException(); 
     } 

    } 

    public Money getTarifaDeSaltos(Boolean pTieneTarjeta, Integer pSaltos) throws NoExisteTarifaException, ErrorEnGetTarifaException { 
     TipoTarifa tipoTarifa; 
     if(pTieneTarjeta){ 
      tipoTarifa = TipoTarifa.Tramo1; 
     }else{ 
      tipoTarifa = TipoTarifa.Ocasional; 
     } 
     Tarifa laTarifa = null; 
     try { 
      dao.openCurrentSession(); 
      laTarifa = dao.getTarifa(tipoTarifa); 
      dao.closeCurrentSession(); 
      return laTarifa.getTarifaParaLosSaltos(pSaltos); 
     } catch (HibernateException e) { 
      System.err.println("Error HibernateException: " + e.getMessage()); 
      e.printStackTrace(); 
      throw new ErrorEnGetTarifaException(tipoTarifa); 
     } 

    } 

} 

这是一张我的终点代码:

@Path("FareManager") 
public class TarifasService { 

private PtDaoService dao; 
    ... 
    @ValidateOnExecution 
    @GET 
    @Consumes(MediaType.TEXT_PLAIN) 
    @Produces(MediaType.APPLICATION_JSON) 
    @Path("{operator}/fare") 
    public Response getTarifa(
     @NotNull @PathParam("operator") String pOperator, 
     @NotNull @QueryParam("start_lat") Double pOriginLatitude, 
     @NotNull @QueryParam("start_lon") Double pOriginLongitude, 
     @NotNull @QueryParam("end_lat") Double pDestinationLatitude, 
     @NotNull @QueryParam("end_lon") Double pDestinationLongitude, 
     @QueryParam("user_id") String pUserIdentification, 
     @QueryParam("provider") String pTransportProvider, 
     @QueryParam("card") Boolean pCard 
    ){ 

     String json = ""; 
     try { 

      if(pOperator==null || pOriginLatitude==null || pOriginLongitude==null || pDestinationLatitude==null || pDestinationLongitude==null || pCard==null || pTransportProvider==null){ 
      String[] params = {"operator", "start_lat", "start_lon", "end_lat", "end_lon", "card", "provider"}; 
       throw new ParametrosInsuficientesException(params); 
      } 

      Integer saltos = dao.getCantidadSaltos(pOriginLatitude, pOriginLongitude, pDestinationLatitude, pDestinationLongitude); 

      Money tarifa = dao.getTarifaDeSaltos(pCard, saltos); 
      BigDecimal precio = tarifa.getAmount(); 
      Currency moneda = tarifa.getCurrencyUnit().toCurrency(); 

      FareResponse response = new FareResponse(pTransportProvider, precio, moneda); 
      json = mWriter.writeValueAsString(response); 
      logHelper.logGetTarifa(pOriginLatitude, pOriginLongitude, pDestinationLatitude, pDestinationLongitude, precio, moneda, saltos, pCard, pOperator, pUserIdentification, pTransportProvider); 
      return Response.ok(json, MediaType.APPLICATION_JSON).build(); 
     } catch (Exception e) { 
      System.err.println("Error: " + e.getLocalizedMessage()); 
      e.printStackTrace(); 
      ExceptionResponse errResp = new ExceptionResponse(e); 
      try { 
       json = mWriter.writeValueAsString(errResp); 
       return Response.serverError().tag("Error").entity(json).build(); 
      } catch (JsonProcessingException e1) { 
       System.err.println("Error: " + e.getLocalizedMessage()); 
       e.printStackTrace(); 
       return Response.serverError().tag("Error").build(); 
      } 
     } 
    } 

的事情是,Web服务应允许多个请求并发的方法相同。如果我在一次执行的方法多次(在浏览器中,按几次F5例如),我得到异常痕迹,似乎是随机的。

有什么问题,你可以在我的代码看?

在此先感谢

编辑 这是例外:

14:05:00.135 [http-apr-9090-exec-6] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - This statement has been closed. 
    Error HibernateException: could not extract ResultSet 
    org.hibernate.exception.GenericJDBCException: could not extract ResultSet 
     at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) 
     at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) 
     at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97) 
     at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79) 
     at org.hibernate.loader.Loader.getResultSet(Loader.java:2115) 
     at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1898) 
     at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1874) 
     at org.hibernate.loader.Loader.doQuery(Loader.java:919) 
     at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) 
     at org.hibernate.loader.Loader.doList(Loader.java:2610) 
     at org.hibernate.loader.Loader.doList(Loader.java:2593) 
     at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2422) 
     at org.hibernate.loader.Loader.list(Loader.java:2417) 
     at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:109) 
     at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1787) 
     at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:363) 
     at com.ingartek.dao.PtDao.getMunicipioByCoor(PtDao.java:192) 
     at com.ingartek.dao.PtDaoService.getCantidadSaltos(PtDaoService.java:326) 
     at com.ingartek.ws.tarifas.TarifasService.getTarifa(TarifasService.java:195) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 
     at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) 
     at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) 
     at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) 
     at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) 
     at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) 
     at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) 
     at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) 
     at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) 
     at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) 
     at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) 
     at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) 
     at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
     at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
     at org.glassfish.jersey.internal.Errors.process(Errors.java:267) 
     at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) 
     at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) 
     at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) 
     at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) 
     at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) 
     at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) 
     at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) 
     at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
     at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
     at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
     at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) 
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) 
     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) 
     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) 
     at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2500) 
     at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2489) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
     at java.lang.Thread.run(Unknown Source) 
    Caused by: org.postgresql.util.PSQLException: This statement has been closed. 
     at org.postgresql.jdbc.PgStatement.checkClosed(PgStatement.java:893) 
     at org.postgresql.jdbc.PgStatement.getMaxRows(PgStatement.java:479) 
     at org.postgresql.jdbc.PgStatement.createResultSet(PgStatement.java:181) 
     at org.postgresql.jdbc.PgStatement$StatementResultHandler.handleResultRows(PgStatement.java:231) 
     at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1947) 
     at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:200) 
     at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:424) 
     at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:161) 
     at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:114) 
     at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70) 
     ... 65 more 
    Error: Error a la hora de consultar la cantidad de saltos. 
    com.ingartek.exception.ErrorEnGetCantidadSaltosException: Error a la hora de consultar la cantidad de saltos. 
     at com.ingartek.dao.PtDaoService.getCantidadSaltos(PtDaoService.java:336) 
     at com.ingartek.ws.tarifas.TarifasService.getTarifa(TarifasService.java:195) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 
     at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) 
     at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) 
     at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) 
     at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) 
     at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) 
     at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) 
     at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) 
     at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) 
     at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) 
     at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) 
     at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) 
     at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
     at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
     at org.glassfish.jersey.internal.Errors.process(Errors.java:267) 
     at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) 
     at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) 
     at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) 
     at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) 
     at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) 
     at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) 
     at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) 
     at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
     at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
     at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
     at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) 
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) 
     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) 
     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) 
     at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2500) 
     at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2489) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
     at java.lang.Thread.run(Unknown Source) 
+0

什么是你得到的例外呢? – Thierry

+0

@Thierry我添加了这个异常。谢谢! – russellhoff

回答

1

我看到3个问题:

  1. 你的事务管理是错误的
  2. 你道是不是线程安全(这是触发stacktrace的这一点见)。
  3. 您在服务水平

约1隐藏例外,你应该在finally块提交TX /关闭休眠会话。

关于2,你不能使用单的字段来存储当前TX也不当前会话。那么不完全正确,但有状态的对象应该包装在无状态对象的ThreadLocal字段中。这是比较复杂的管理,你应该使用库(例如spring-framework tx services)。

关于3,如果服务是隐藏例外,你永远不知道在控制器中如果发生错误或没有,如果你要继续处理或不...

+0

我修改了PtDao,使它不遵循单例模式。 1)我在try块的末尾提交并在每个catch块的末尾回滚。关于finally块,你是对的,我应该在那里结束会议。 2)也许它不是线程安全的,因为它跟随Singleton模式? 3)你是否建议我不要将所有异常包含在捕获异常(超类)的try-catch块中?你会建议我学习Spring框架吗?我从哪里开始?我愿意这样做,但我不知道从哪里开始。非常感谢! – russellhoff

+1

2.是:在多线程环境中使用的单例应该是无状态的。3:您可以将hibernate异常封装在声明的扩展RuntimeException的声明中,这样您不必在方法签名中声明它,并且配置Web容器以在异常情况下显示通用错误页面。我强烈建议学习spring,阅读它的文档,它的代码源。即使你不使用它,你也会学到很多好的实践。但最好的当然是使用它;)官方文档/教程已经足够清楚,开始学习它。 – Thierry