存储过程未执行

时间:2015-07-07 20:23:54

标签: jdbc ejb

我真的需要你的帮助。我有一个调用oracle存储过程的JDBC代码。这是具有代码的类:

public class DAOImpl {

    private String sql = "{call MAIN.SP_CALC(?,?,?,?,?)}";
    private Connection conn = null;

    public DAOImpl(Connection conn) {
        this.conn = conn;            
    }

    @Override
    public synchronized void executeSP(String year, String month, Long id) throws SQLException {
       try (CallableStatement cs = conn.prepareCall(sql);) {
           cs.setObject(1, id);
           cs.setObject(2, year);
           cs.setObject(3, month);
           cs.setObject(4, 0);
           cs.registerOutParameter(5, Types.INTEGER);
           cs.execute();
       }
    }

}

我有两个这个类的客户端,一个JavaSE Tester类和一个无状态EJB。 JavaSE main()方法有以下代码:

      try {
            DriverManager.registerDriver(new OracleDriver());
            Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
            DAOImpl dao = new DAOImpl(conn);            
            dao.executeSP("2015", "02", 99561010l);
        } catch (SQLException ex) {
            Logger.getLogger(SPTester.class.getName()).log(Level.SEVERE, null, ex);
        }

无状态EJB具有以下其他代码:

        try {             
            conn = ds.getConnection();
            DAO dao = DAOImpl(conn);                
            dao.executeSP("2015", "02", 99561010l);                
        } catch (SQLException ex) {
            throw new SQLException(ex);
        } finally {                
            conn.close();
        }

ds是一个实例变量,作为DataSource注入EJB,该数据源来自在oracle.jdbc.xa.client.OracleXADataSource类型的glassfish中声明的JDBC连接池。 JavaSE程序的变量DB_URL,USER,PASS具有使用JDBC连接池的相同值

正如您将注意到的,唯一的区别是Connection对象。 JavaSE和EJB都使用ojdbc6.jar驱动程序。两者都使用java 1.7.0_u2,这就是我使用try-with-resources的原因。

问题是只有JavaSE才有效!它们都经过几秒钟的处理后返回,但只有JavaSE程序才能工作。我已经尝试了很多东西.. CMT和BMT EJB,包装和解包的id类型,同步和非同步方法等。我需要在EJB中使用此代码:(

我的EJB出了什么问题?

提前致谢

1 个答案:

答案 0 :(得分:0)

这是EJB的CMT版本

@Stateless
@LocalBean
@Interceptors({PropagateSessionContextInterceptor.class})
public class CalcBean extends BaseContextSessionBean {

@Resource(mappedName = "jdbc/maestro")
protected DataSource ds;
public Connection conn = null;

public void executeSP(String year, String month, Long id) throws SQLException {

   try {
        conn = ds.getConnection();
        DAO dao = DAOImpl(conn); 
        dao.executeSP("2015", "02", 99561010l);                                 
    } catch (SQLException ex) {
        throw new SQLException(ex);
    } finally {                
        conn.close();
    }


 }

}

这是EJB的BMT版本

@Stateless
@LocalBean
@Interceptors({PropagateSessionContextInterceptor.class})
@TransactionManagement(TransactionManagementType.BEAN)
public class CalcBean extends BaseContextSessionBean {

@Resource(mappedName = "jdbc/maestro")
protected DataSource ds;
public Connection conn = null;

@Resource
UserTransaction tx;

 public void executeSP(String year, String month, Long id) throws SQLException {
   try {
       try {
            tx.begin();
            conn = ds.getConnection();
            DAO dao = DAOImpl(conn); 
            dao.executeSP("2015", "02", 99561010l);                 
            tx.commit();
        } catch (SQLException ex) {
            throw new SQLException(ex);
        } finally {                
            conn.close();
        }
   } catch (Exception e) {
       throw new EJBException(e);
   } 

 }

}

public class BaseContextSessionBean {

 @Resource
 public SessionContext ctx;

}

public class PropagateSessionContextInterceptor {

  @AroundInvoke
  public Object myInterceptor(InvocationContext ctx) throws Exception
  {
   BaseContextSessionBean sb = (BaseContextSessionBean)ctx.getTarget();
   ControlListener.setSessionContext(sb.ctx);
   Object o = ctx.proceed();
   return o;
  }

}

public interface DAO { 
   public void executeSP(String year, String month, Long id) throws SQLException;
}

我不知道BaseContextSessionBean和PropagateSessionContextInterceptor的原因。最初,EJB使用了无用的JDBC框架(使用这些类),所以我用DAOImpl类替换它。我使用DAO接口来解耦实现,DaoImpl已经执行(在EJB中,DAOImpl实现了DAO,我忘了把它放在早期的帖子中)