實體 Bean 是 JPA 核心,代表資料表記錄與 Java 物件的映射。本文從零開始,完整示範:資料庫準備、JBoss 資料源配置、實體類別定義、persistence.xml 設定、Session Bean 操作 EntityManager、客戶端呼叫的端到端流程。
id (PK) | name | password_md5 1 | bill | TaokQpoNJQb02eafO/JgYw==
在 $JBOSS_HOME/server/default/deploy 建立 mysql-ds.xml:
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>MyPIM</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/pim</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>1234</password>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
關鍵步驟:MySQL JDBC 驅動 JAR (mysql-connector-java-x.x.x.jar) 複製至 $JBOSS_HOME/server/default/lib。
package entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "t_users")
public class User {
private int id;
private String name;
private String password;
@Id
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Column(name = "password_md5") // 欄位名映射
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
@Entity:聲明為 JPA 實體@Table(name="t_users"):指定映射資料表@Id:主鍵欄位@Column(name="password_md5"):屬性名與欄位名不同時映射位於 META-INF/persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="https://java.sun.com/xml/ns/persistence"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/persistence
https://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="myentity">
<jta-data-source>java:/MyPIM</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="none" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
</properties>
</persistence-unit>
</persistence>
name="myentity":持久化單元名稱,與 @PersistenceContext(unitName="myentity") 對應jta-data-source:引用 JBoss 資料源 JNDI 名稱hibernate.dialect:指定資料庫方言,生成正確 SQLpackage service;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import entity.User;
@Stateless
public class UserBean implements UserBeanRemote {
@PersistenceContext(unitName = "myentity")
protected EntityManager em;
@Override
public String getPassword() {
User user = em.find(User.class, 1); // 根據 PK 查詢
return user.getPassword();
}
}
| 方法 | 用途 | |
|---|---|---|
find(Class, PK) | 根據主鍵查詢單筆,回傳實體或 null | |
persist(entity) | 新增實體 (INSERT) | |
merge(entity) | 更新/合併實體 (UPDATE/INSERT) | |
remove(entity) | 刪除實體 (DELETE) | |
createQuery(jpql) | 建立 JPQL 查詢 |
| 錯誤 | 原因 | 解決 |
|---|---|---|
NameNotFoundException | JNDI 名稱錯誤 | 檢查 JBoss 控制台 JNDI 視圖確認實際綁定名稱 |
No Persistence provider | persistence.xml 路徑錯誤 | 確認在 META-INF 根目錄,且 JAR 包含該檔案 |
Unknown entity | 實體類別未被掃描 | 檢查 persistence.xml 是否包含實體類別或掃描配置 |
JDBC Driver not found | 驅動 JAR 未放入 lib | 複製 mysql-connector-java.jar 至 server/default/lib |