JBoss 3.2.x 基於 JMX 微內核,Hibernate 實現 org.hibernate.jmx.HibernateService MBean 接口,可作為 JMX 服務部署,享受:
# 複製到 JBoss 共享庫目錄
cp hibernate3.jar \
hibernate-annotations.jar \
ehcache-*.jar \
commons-collections-*.jar \
dom4j-*.jar \
javassist-*.jar \
jta.jar \
$JBOSS_HOME/server/default/lib/
文件名:hibernate-service.xml(放入 SAR 包的 META-INF/)
<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="org.hibernate.jmx.HibernateService"
name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
<!-- 依賴服務啟動順序 -->
<depends>jboss.jca:service=RARDeployer</depends>
<depends>jboss.jca:service=LocalTxCM,name=MyDataSource</depends>
<!-- 映射文件路徑(相對 SAR 根目錄)-->
<attribute name="MapResources">mappings/User.hbm.xml</attribute>
<!-- JNDI 綁定名 -->
<attribute name="JndiName">java:/HibernateFactory</attribute>
<!-- 數據源 JNDI -->
<attribute name="Datasource">java:/MyDataSource</attribute>
<!-- 方言 -->
<attribute name="Dialect">org.hibernate.dialect.SQLServerDialect</attribute>
<!-- 事務策略:BMT 用 JTATransactionFactory,CMT 用 CMTTransactionFactory -->
<attribute name="TransactionStrategy">org.hibernate.transaction.JTATransactionFactory</attribute>
<!-- JBoss 事務管理器查找 -->
<attribute name="TransactionManagerLookupStrategy">
org.hibernate.transaction.JBossTransactionManagerLookup
</attribute>
<attribute name="UserTransactionName">UserTransaction</attribute>
<!-- 可選:二級緩存配置 -->
<attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
<attribute name="ShowSql">false</attribute>
</mbean>
</server>
# 目錄結構
myapp.sar/
├── com/myapp/model/ # 持久化類
├── mappings/
│ └── User.hbm.xml # 映射文件
└── META-INF/
├── jboss-service.xml # 上述 MBean 配置
└── MANIFEST.MF
# 打包命令
cd myapp.sar
jar cf ../myapp.sar .
cp ../myapp.sar $JBOSS_HOME/server/default/deploy/
@Stateless
public class BookServiceBean implements BookService {
@Resource SessionContext ctx;
public void createBook() {
try {
InitialContext ic = new InitialContext();
SessionFactory sf = (SessionFactory) ic.lookup("java:/HibernateFactory");
Session session = sf.openSession();
UserTransaction tx = ctx.getUserTransaction();
tx.begin();
Book book = new Book();
book.setId(111L);
book.setName("JBoss & Hibernate");
book.setPrice(111f);
session.save(book);
tx.commit();
session.close();
} catch (Exception e) {
throw new EJBException(e);
}
}
}
| 屬性 | BMT 值 | CMT 值 | 說明 |
|---|---|---|---|
| TransactionStrategy | JTATransactionFactory | CMTTransactionFactory | 事務邊界管理方式 |
| TransactionManagerLookupStrategy | JBossTransactionManagerLookup | JBossTransactionManagerLookup | 獲取 JBoss TM |
| UserTransactionName | UserTransaction | N/A | BMT 時 JNDI 名 |
| 現象 | 原因 | 解決 |
|---|---|---|
| ClassNotFound: HibernateService | hibernate3.jar 未放入 server/lib | 複製到共享庫目錄並重啟 |
| DataSource 不可用 | depends 配置錯誤或 DS 未部署 | 檢查 *-ds.xml 部署、JNDI 名一致 |
| 映射文件找不到 | MapResources 路徑錯誤 | 相對 SAR 根目錄,區分大小寫 |
| 事務不回滾 | TransactionStrategy 與 Bean 類型不匹配 | BMT↔JTA, CMT↔CMT 對應正確 |
| LazyInitializationException | Session 關閉後訪問延遲加載集合 | Open Session in View / fetch join / DTO 投影 |
<mbean code="org.hibernate.jmx.HibernateService"
name="jboss.jca:service=HibernateFactory,name=CustomerFactory">
<attribute name="JndiName">java:/CustomerFactory</attribute>
<attribute name="Datasource">java:/CustomerDS</attribute>
<attribute name="MapResources">mappings/customer/*.hbm.xml</attribute>
</mbean>
<mbean code="org.hibernate.jmx.HibernateService"
name="jboss.jca:service=HibernateFactory,name=OrderFactory">
<attribute name="JndiName">java:/OrderFactory</attribute>
<attribute name="Datasource">java:/OrderDS</attribute>
<attribute name="MapResources">mappings/order/*.hbm.xml</attribute>
</mbean>
JBoss 4.0+ 內建 Hibernate,配置簡化為 hibernate.cfg.xml + jboss-service.xml。若新建項目,建議直接使用 JBoss 4.x/5.x/7.x (WildFly) 獲得原生集成支持。