EJB3 DAO无状态会话bean设计(使用JDBC连接)

EJB3 DAO无状态会话bean设计(使用JDBC连接),jdbc,ejb-3.0,dao,stateless-session-bean,Jdbc,Ejb 3.0,Dao,Stateless Session Bean,我正在为一个EJB3项目设计一个DAO层,它们是无状态会话bean。由于某些原因,DAO的一部分不会使用JPA,而是直接使用JDBC访问数据库 因此,我没有注入EntityManager,而是注入了一个数据源,从中可以获得连接、创建会话等等。。。为了避免重复的工作,我制作了一个POJO基类,它在开始时从数据源获取连接,并在销毁之前关闭连接。所有JDBCDAO都扩展了它,所以他们不需要自己做这样的工作。基类如下所示: public abstract class MemDBDAO { @R

我正在为一个EJB3项目设计一个DAO层,它们是无状态会话bean。由于某些原因,DAO的一部分不会使用JPA,而是直接使用JDBC访问数据库

因此,我没有注入EntityManager,而是注入了一个数据源,从中可以获得连接、创建会话等等。。。为了避免重复的工作,我制作了一个POJO基类,它在开始时从数据源获取连接,并在销毁之前关闭连接。所有JDBCDAO都扩展了它,所以他们不需要自己做这样的工作。基类如下所示:

public abstract class MemDBDAO {

    @Resource(mappedName = "java:MagicCardDS")
    private DataSource dataSource;
    protected Connection dbConnection;

    @PostConstruct
    protected void startUp() {
        try {
            dbConnection = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();  
        }
    }

    @PreDestroy
    protected void shutDown() {
        try {
            dbConnection.close();
        } catch (SQLException e) {
            e.printStackTrace();  
        }
    }

}
@Stateless
public class SessionDAOBean extends MemDBDAO implements SessionDAO {


    @Override
    public void createSession(String sessionId, Integer userId) {
        try {
            PreparedStatement statement = dbConnection.prepareStatement(
                    "INSERT INTO session VALUES(?, ?, ?, ?)");
            statement.setString(1, sessionId);
            statement.setInt(2, userId);
            statement.setBoolean(3, false);
            statement.setTimestamp(4, new Timestamp(System.currentTimeMillis()));
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();  
        }
    }
...
例如,一个JDBC DAO如下所示:

public abstract class MemDBDAO {

    @Resource(mappedName = "java:MagicCardDS")
    private DataSource dataSource;
    protected Connection dbConnection;

    @PostConstruct
    protected void startUp() {
        try {
            dbConnection = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();  
        }
    }

    @PreDestroy
    protected void shutDown() {
        try {
            dbConnection.close();
        } catch (SQLException e) {
            e.printStackTrace();  
        }
    }

}
@Stateless
public class SessionDAOBean extends MemDBDAO implements SessionDAO {


    @Override
    public void createSession(String sessionId, Integer userId) {
        try {
            PreparedStatement statement = dbConnection.prepareStatement(
                    "INSERT INTO session VALUES(?, ?, ?, ?)");
            statement.setString(1, sessionId);
            statement.setInt(2, userId);
            statement.setBoolean(3, false);
            statement.setTimestamp(4, new Timestamp(System.currentTimeMillis()));
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();  
        }
    }
...
当我将其部署到JBoss 6应用程序服务器时,我收到以下错误消息:

20:51:12,546 INFO  [org.jboss.resource.connectionmanager.CachedConnectionManager] Closing a connection for you.  Please close them yourself: org.jboss.resource.adapter.jdbc.jdk6.WrappedConnectionJDK6@9bb04a: java.lang.Throwable: STACKTRACE
    at org.jboss.resource.connectionmanager.CachedConnectionManager.registerConnection(CachedConnectionManager.java:278) [:6.1.0.Final]
    at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:524) [:6.1.0.Final]
    at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:941) [:6.1.0.Final]
    at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:89) [:6.1.0.Final]
    at piapox.com.magiccard.server.dao.MemDBDAO.startUp(MemDBDAO.java:32) [:]
    at piapox.com.magiccard.server.dao.SessionDAOBean.startUp(SessionDAOBean.java:35) [:]
...
那么我应该如何设计JDBCDAO会话bean呢?有什么好的图案吗?
谢谢

可能是JBoss正在监视建立的连接。服务器似乎正在尝试关闭连接,即使它已经关闭,这些消息也可以忽略。消息可能不会中断正常处理&可以通过更改jboss配置文件来禁用

回调方法
@PostConstruct
@PreDestroy
由容器处理。它的供应商特定于为每个方法调用创建和销毁无状态会话bean实例。和池状态一样,bean实例可能会长时间处于活动状态

最好在方法本身中打开连接,并在退出
createSession
方法之前关闭连接,如果运行时出现异常,最好使用
finally


您也可以参考JBoss的报告。

谢谢,您是对的,将getConnection从生命周期函数移动到每个逻辑函数后,异常将消失。