一樣是參照
http://theopentutorials.com/examples/java-ee/ejb3/how-to-create-ejb3-jpa-project-in-eclipse-jboss-as-6-1/
延續上篇~上篇是搞定 JNDI
這邊是建個簡單的 EJB...
差別就是,這邊先使用簡單的 Local ,所以有改寫 client 取的來源,還有一些其他的筆記~
6. 設定 persistence.xml
環境設定一直都是個惡夢...雖然久久一次(通常也是只建那麼一次...),但是每次都會出槌Orz...
classes/META-INF/persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="mypersistence" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/PostgresDS</jta-data-source>
<properties>
<property name="showSql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
</properties>
</persistence-unit>
</persistence>
重點就是,EJB 通常是個 jar/ear 檔,所以這個檔的位置是放在 classes/META-INF 裡面的~~如果想放在 war 裡面的話,就是自己手動 copy 到 webapp/WEB-INF/classes/META-INF/persistence.xml 裡面~~放錯位置,就會一直找不到Orz..
至於因為是用 JBoss ,內建 hibernate ,所以沒設定,就是默認為 hibernate 的 jpa..hibernate 設定大概就是要依DB定 hibernate.dialect
7. Entity
對應 DB 的 Enitity Bean..現在有 annotation 就方便很多~
因為是用 hibernate,也等同 hibernate 的 O/R mapping
(大概就是 pojo, bo(business object),印象中就是 EJB 概念中有比較活在潮流裡的項目,不過是因為 hibernate 發揚光大的...但真心的說,身為 SQL 派的我討厭hibernate..)
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Column;
@Entity(name = "yyy")
public class AAAA implements Serializable {
private static final long serialVersionUID = 1L;
public AAAA() {
super();
}
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="yyy_id_seq")
@SequenceGenerator(name="yyy_id_seq", sequenceName="yyy_id_seq", allocationSize=1)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String complete;
Postgresql 如果用 SERIAL 當 type ,其實是個 seq,就設定上要再訂一下。
8. Business Interface
這邊有分 Local 和 Remote,因為 Local 比較簡單,反正之後也是用這個...就先用 Local...
(這層就差不多是 spring 的 service 層(interface))
import javax.ejb.Local;
@Local
public interface AAAAService {
/**
* query all
* @return all data
*/
public List<AAAA> findAll();
/**
* insert
* @param data
*/
public void insert(AAAA data);
9. Business Logic
實做 business interface...在這邊連結 persistence 的設定,EJB 在這裡可以就下 sql 直接 access db 了
(就也是spring 的 serviceImp,至於底下要不要多一層 dao,看人看架構吧。)
另外因為是套用 hibernate ,所以就要用 hsql 下(個人覺得也是惡夢 Orz)
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
@Stateless
public class AAAAServiceBean implements AAAAService {
@PersistenceContext(unitName = "mypersistence")
private EntityManager entityManager;
public AAAAServiceBean() {
}
/**
* query all
* @return all data
*/
public List<AAAA> findAll() {
String q = "FROM "+AAAA.class.getName();
Query query = entityManager.createQuery(q);
List<AAAA> lst = query.getResultList();
return lst;
}
/**
* search data according to keyword
* @param keyword for search
* @return list of data
*/
public List<AAAA> search(String keyword) {
if(keyword == null || keyword.trim().length() == 0) {
return findAll();
}
String q = "FROM "+AAAA.class.getName()+" t WHERE t.name LIKE :keyword";
Query query = entityManager.createQuery(q).setParameter("name", keyword);
List<AAAA> lst = query.getResultList();
return lst;
}
/**
* insert
* @param data
*/
public void insert(AAAA data) {
entityManager.persist(data);
}
/**
* update data by key (id)
* @param data
*/
public void update(AAAA data) {
entityManager.merge(data);
}
/**
* delete data by key (id)
* @param data
*/
public void delete(AAAA data) {
entityManager.remove(data);
}
10. Client
在 EJB 會弄個 Client 來呼叫 Bussiness,基本上也只是去查 Context Name 弄出來
(spring 是把 service 做成 spring 的 bean 來注入,EJB 就得自己去 lookup...所以要知道 service 叫什麼名字是很重要的~那個 cli 指令就還蠻好用的)
client 就沒有什麼特別的 annotation..重點只是在怎麼拿到 Bussiness Instance
Context initContext = new InitialContext();
Context ctx = (Context) initContext.lookup("java:app/MYWEBAPP");
AAAService bean = (AAAService) context.lookup("AAAServiceBean");
List<AAA> list = bean.findAll();
bean.insert(....);
貼一下,如果在 cli 看到的 ServiceBean 大概就會長這樣子
(其實在 context naming 裡,很多 scope 都會有,只是我想就用 app,自己範圍的就好)
"applications" => {"MYWEBAPP.war" => {
"java:app" => {
...
"MYWEBAPP" => {
"class-name" => "javax.naming.Context",
"children" => {
...
"AAAAServiceBean" => {
"class-name" => "xxx.yyy.businesslogic.AAAAServiceBean",
"value" => "?"
},
...
在這邊也可以看一下 serviceBean 有沒有被正確的放進來,然後就可以連線測試了~
沒有留言:
張貼留言