|
查看: 2577|回复: 7
|
[请教][Java]EJB3 fetch=FetchType.Lazy 的问题
[复制链接]
|
|
|
之前一直用着Eager Fetch , 都没有问题。 可是现在, 遇到要做 Tree expansion , Eager Fetch 占用太大资源, 而且有问题。 所以才正式使用 Lazy fetch 。
可是Lazy fetch 没有像理论上的去做 fetch when accessing 。
我简略来说我的问题。。
class Material
{
:
:
@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, mappedBy="material", targetEntity=BOM.class)
private List<BOM> boms;
@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, mappedBy="material", targetEntity=BomDetail.class)
private List<BomDetail> bomDetails;
:
:
public BOM getBomByType(String type)
{
System.out.println("boms = " + getBoms());
if(boms != null)
{
for(BOM bom : boms)
{
//System.out.println("[Material.java] getBomByType() : " + bom.getType() + " type : " + type);
if(bom.getType().equals(type))
{
//System.out.println("Before return bom");
return bom;
}
}
}
else
{
System.out.println("[Material.java] boms is null");
}
return null;
}
}
Lazy Fetch - 我在call getBomByType() , 得到的是
[Material.java] boms is null
我上网搜寻了资料, 有者说要property access , 不能用field access。
我尝试了很多方式都不行, 又无从debug 起。
想请教大家下, 有没有遇过这样的问题, 是如何解决的? 要如何debug 这种问题 。。 |
|
|
|
|
|
|
|
|
|
|
发表于 7-2-2009 08:14 PM
|
显示全部楼层
把Business Method放在Service/Dao内,透过PersistanceManager取得对象之后再call getBoms()和getBomDetails()。
(JPA的Entity是一种Anemic Domain Model, 不能包涵Business Methods) |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 8-2-2009 02:30 PM
|
显示全部楼层
谢谢你的回复。。
我本来就是如你所说的把business method 写在service layer 。 但是有问题, 我才采用这个方式。
当时的问题时, 我写的service layer, 在一个service session bean , call 另外一个service session bean 时, 提取 Persistence manager 没有value.
但是从web client 透过JNDI 就能够拿到。
我对JPA 的认识不深, 不知道我用的方式对不对。
我尝试解释我的方式。
public abstract class BaseService {
@PersistenceContext(unitName = "xxxx")
protected EntityManager _em;
:
:
}
@Stateless
@Local(ISalesOrderServiceLocal.class)
@Remote(ISalesOrderServiceRemote.class)
public class SalesOrderService extends BaseService implements ISalesOrderServiceLocal, ISalesOrderServiceRemote
{
public void methodA()
{
BomService bomService = new BomService();
bomService.methodB(); <---- NullPointerException
}
}
@Stateless
@Local(IBomServiceLocal.class)
@Remote(IBomServiceRemote.class)
public class BomService extends BaseService implements IBomServiceLocal, IBomServiceRemote
{
public void methodB()
{
:
:
_em.createQuery(....); <---- _em == null
}
}
这种方式是对的吗? |
|
|
|
|
|
|
|
|
|
|
发表于 8-2-2009 06:54 PM
|
显示全部楼层
问题出现在这里。
BomService bomService = new BomService();
你应该要从EJB container用JNDI获取BomService,而不是Instantiate。还有一点就是Stateless bean只需要用@Stateless就可以了,@Local/@Remote是用在Interface的Declaration.
EJB3应该还有一个更快捷的方法 -- Dependency Injection;就是直接用 @EJB annotation
就好像这样:
- @Stateless
- public class SalesOrderService extends BaseService implements ISalesOrderServiceLocal, ISalesOrderServiceRemote
- {
- private BomService bomService;
- @EJB(beanName="xxx")
- public void setBomService(BomService bs){
- this.bomService = bs;
- }
- public void methodA()
- {
- bomService.methodB();
-
- }
- }
复制代码 |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 9-2-2009 11:19 AM
|
显示全部楼层
多谢苦瓜汤的指点, 困扰我数星期的问题解决了, 果然是Java 高手。
我使用了 @EJB 来解决, 有一点不同的是, 我是用declare 一个interface variable 不是一个bean instance, 因为在OpenEJB 的mailing list 有说到, EJB3.0 里的@EJB 需要一个interface , 在EJB3.1 里才接受 bean instance
参考:
http://www.nabble.com/A-little-help-with-openejb-jar.xml-td19332950s134.html
再请问下, @EJB 有在Hibernate 里吗, 如果没有的话, 是不是就要用一般的JNDI lookup 的方式了? |
|
|
|
|
|
|
|
|
|
|
发表于 9-2-2009 08:07 PM
|
显示全部楼层
原帖由 jangancari 于 9-2-2009 11:19 AM 发表 
多谢苦瓜汤的指点, 困扰我数星期的问题解决了, 果然是Java 高手。
我使用了 @EJB 来解决, 有一点不同的是, 我是用declare 一个interface variable 不是一个bean instance, 因为在OpenEJB 的mailing list 有 ...
不客气 我之前也在学习EJB3,可以交流交流。
啊,没错,@EJB的确用Interface就可以了。基本上Hibernate JPA是一个JPA的Implementation,和@EJB没有关系,就好像Oracle Toplink和OpenJPA一样;而@EJB是J2EE1.5的规范,支持J2EE 1.5以上的J2EE-compliant Application Server都可以用。 |
|
|
|
|
|
|
|
|
|
|
发表于 9-2-2009 10:02 PM
|
显示全部楼层
原帖由 苦瓜汤 于 9-2-2009 08:07 PM 发表 
不客气 我之前也在学习EJB3,可以交流交流。
啊,没错,@EJB的确用Interface就可以了。基本上Hibernate JPA是一个JPA的Implementation,和@EJB没有关系,就好像Oracle Toplink和OpenJPA一样;而@EJB是J2EE1. ...
Hibernate 并不叫JPA.. 而是ORM..
JPA (Java Persistence API) 是 Java EE 新的持久化标准,
借鉴与吸收了现有的ORM product 弄出来的新东西..
目的是想取代目前所有ORM product, 称王.. |
|
|
|
|
|
|
|
|
|
|
发表于 9-2-2009 11:21 PM
|
显示全部楼层
原帖由 jasonmun 于 9-2-2009 10:02 PM 发表 
Hibernate 并不叫JPA.. 而是ORM..
JPA (Java Persistence API) 是 Java EE 新的持久化标准,
借鉴与吸收了现有的ORM product 弄出来的新东西..
目的是想取代目前所有ORM product, 称王..
我想你误会了我的意思, Hibernate JPA是指Hibernate提供的Persistence Provider,而不是指整个Hibernate项目。
http://www.hibernate.org/397.html
[ 本帖最后由 苦瓜汤 于 9-2-2009 11:36 PM 编辑 ] |
|
|
|
|
|
|
|
|
| |
本周最热论坛帖子
|