我正在为EJB3项目设计一个DAO层,它们是无状态会话bean。出于某种原因,部分DAO不会使用JPA,它们直接使用JDBC访问数据库。
因此,我注入了一个数据源而不是注入EntityManager,我可以从中获取Connection,创建Session等等......为了避免重复工作,我创建了一个POJO BaseClass,从数据源获取连接在开始和关闭它之前毁灭。所有JDBC DAO都扩展它,因此它们不需要自己做这样的工作。 BaseClass看起来像这样:
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();
}
}
}
例如,一个JDBC DAO看起来像这样:
@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) [:]
...
那么我应该如何设计JDBC DAO会话bean?有什么好的模式吗? 谢谢!
答案 0 :(得分:2)
JBoss可能正在监控建立的连接。似乎服务器试图关闭连接,即使它已经关闭,这些消息可以被忽略。可能消息不会中断正常处理&可以通过更改jboss配置文件来禁用。
回拨方法@PostConstruct
& @PreDestroy
由容器处理。它的供应商具体到创建&为每个方法调用销毁无状态会话bean实例。与汇集状态一样,bean实例可能会长时间处于活动状态。
最好在方法本身中打开连接&在createSession
方法退出之前关闭它,如果在运行时出现异常,则首选finally
。
你也可以参考这个与JBoss一起报道的bug。