之前, 開發都是在Oracle + EclipseLink JPA. 整個使用上都沒有問題. 但是直到, 要把整套移植到 MSSQL 上面時, 就會出現一些問題.
原有的邏輯.
1. doc1 = em1.perserient(doc1) // (會產生 doc1的ID , 由資料庫產生, 不透過程式)
2. doc2.setDoc1Id(doc1.getId()) // 設定 doc1 doc2 reference
3. doc2 = em2.perserient(doc2) // 存放 Doc2
4. transaction commit
在 Orcale + eclipseLink Jpa 活的好好的.
一移植到 mssql 後, doc2.getDoc1Id 會是 null.
不過, 改用 hibernate jpa 以後, 程式就可以順利過關, 暫時只能先這樣. 以後有研究在討論
2011-05-30
2011-05-18
[JPA] 多個EntityManager Transaction Commit 的Insert Select 問題
[狀況]
最近寫到一個 business logic , 大致的邏輯是這樣
1. Insert Data To TableA
2. Insert Data To TableB
3. Insert Data to TableC Where Select Data From TableA join TableB
之前寫過一次, 用 eclipse JPA 可以在同一個 transaction 中完程. 如果採用 Hibernate 則 第三個步驟是沒有辦法產生的. 所以之前問題有解決.
不過今天遇到, EntityManagerA for 1,3, EntityManagerB for 2.
在同一個 transaction 中, TableC 只會有 TableA 的資料, 不會出現TableB
[實驗結果]
在第一個 transaction 中, 只包含 1, 2 , 第二個transaction 包涵 3 . 則 TableC 中會出現該有的資料, 而不會有遺漏
最近寫到一個 business logic , 大致的邏輯是這樣
1. Insert Data To TableA
2. Insert Data To TableB
3. Insert Data to TableC Where Select Data From TableA join TableB
之前寫過一次, 用 eclipse JPA 可以在同一個 transaction 中完程. 如果採用 Hibernate 則 第三個步驟是沒有辦法產生的. 所以之前問題有解決.
不過今天遇到, EntityManagerA for 1,3, EntityManagerB for 2.
在同一個 transaction 中, TableC 只會有 TableA 的資料, 不會出現TableB
[實驗結果]
在第一個 transaction 中, 只包含 1, 2 , 第二個transaction 包涵 3 . 則 TableC 中會出現該有的資料, 而不會有遺漏
2011-02-10
ORA-24777 發生在 Jee Server
最近用 jpa 搭配 Oracle Database Link Query .用 JPA 搭配 RESOURCE_LOCAL可以執行.
但是, 當程式換成 Session Bean 時會出現.
第一次遇到, google一下....找到解答的網頁 .
1. 設定 Oracle Database 支援 multi-threaded server. (這個工程浩大, 網頁也是不建議作)
2. 改變 create database link 語法. (文章中他們是這樣解的, 不過我沒辦法因為 DB 不是我能動的)
3. 改用 non-XA Driver. (這各在我的案例中是唯一的解法, 因為修改自己的東西最簡單)
結論
經過測試, 第三種方式可以解決我的問題, 因為我要的只是Query 並不牽涉到 Transaction. 所以, 只好新增 DataSource for non-XA .
但是, 當程式換成 Session Bean 時會出現.
ORA-24777: use of non-migratable database link not allowed.
第一次遇到, google一下....找到解答的網頁 .
ORA-24777 When Using XA Driver
解答篇中 提出三種解決問題的方法1. 設定 Oracle Database 支援 multi-threaded server. (這個工程浩大, 網頁也是不建議作)
2. 改變 create database link 語法. (文章中他們是這樣解的, 不過我沒辦法因為 DB 不是我能動的)
3. 改用 non-XA Driver. (這各在我的案例中是唯一的解法, 因為修改自己的東西最簡單)
結論
經過測試, 第三種方式可以解決我的問題, 因為我要的只是Query 並不牽涉到 Transaction. 所以, 只好新增 DataSource for non-XA .
2010-12-03
Query by Page on JPA
在Query 大量的資料時, 如果沒有將資料作 page的動作, 一次抓回來會在吃掉大量的記憶體去產生相關的 class. 如果, 只需要部份資料慢慢取回處理, 可以採用page 的方式去截去資料.
在 JPA 中, Query 這一個物件有
在 Pro JPA 2 page. 194 提到, 可用 stateful session 來達到用 存放在 http session 中, 讓 jsp or javaServer faces 可以 作到 PageQuery
在 JPA 中, Query 這一個物件有
setFirstResult(int startPosition)- setMaxResults(int maxResult)
在 Pro JPA 2 page. 194 提到, 可用 stateful session 來達到用 存放在 http session 中, 讓 jsp or javaServer faces 可以 作到 PageQuery
@Stateful
public class ResultPagerBean implements ResultPager {
@PersistenceContext(unitName="QueryPaging")
private EntityManager em;
private String reportQueryName;
private long currentPage;
private long maxResults;
private long pageSize;
public long getPageSize() {
return pageSize;
}
public long getMaxPages() {
return maxResults / pageSize;
}
public void init(long pageSize, String countQueryName,
String reportQueryName) {
this.pageSize = pageSize;
this.reportQueryName = reportQueryName;
maxResults = em.createNamedQuery(countQueryName, Long.class)
.getSingleResult();
currentPage = 0;
}
public List getCurrentResults() {
return em.createNamedQuery(reportQueryName)
.setFirstResult(currentPage * pageSize)
.setMaxResults(pageSize)
.getResultList();
}
public void next() {
currentPage ;
}
public void previous() {
currentPage--;
if (currentPage < 0) {
currentPage = 0;
}
}
public long getCurrentPage() {
return currentPage;
}
public void setCurrentPage(long currentPage) {
this.currentPage = currentPage;
}
@Remove
public void finished() {}
}
Read-Only entity for JPA
開發系統時會有一些只有Query 不會去 modify 的db query . 在jpa 中 每一個entity 產生後都是會被 managed. 所以, 要怎樣作到 不會被 managed 來造乘Query locked. 在Pro JPA 2 page.191 有提到一個 Optimizing Read-Only Queries 提到兩種方式 :
1. Outside of a Transaction : 將 entity query 的程式段落, 不要包涵在transaction 中. 但是對於 application-managed or extends entity managers 就不是用了.
2. 將Query 封裝在一個 stateless session facade , 在method 宣告 NOT_SUPPORTED. 只要執行到這一個method code, 任何 transaction 都會被 suspended. 已達到read-only 最佳化.
1. Outside of a Transaction : 將 entity query 的程式段落, 不要包涵在transaction 中. 但是對於 application-managed or extends entity managers 就不是用了.
2. 將Query 封裝在一個 stateless session facade , 在method 宣告 NOT_SUPPORTED. 只要執行到這一個method code, 任何 transaction 都會被 suspended. 已達到read-only 最佳化.
@Stateless
public class QueryServiceBean implements QueryService {
@PersistenceContext(unitName="EmployeeService")
EntityManager em;
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public List<Department> findAllDepartmentsDetached() {
return em.createQuery("SELECT d FROM Department d",
Department.class)
.getResultList();
}
// ...
}
訂閱:
文章 (Atom)