佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 2576|回复: 7

[请教][Java]EJB3 fetch=FetchType.Lazy 的问题

[复制链接]
发表于 5-2-2009 10:31 AM | 显示全部楼层 |阅读模式
之前一直用着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 这种问题 。。
回复

使用道具 举报


ADVERTISEMENT

发表于 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

就好像这样:

  1. @Stateless

  2. public class SalesOrderService extends BaseService implements ISalesOrderServiceLocal, ISalesOrderServiceRemote

  3. {

  4.     private BomService bomService;

  5.     @EJB(beanName="xxx")
  6.     public void setBomService(BomService bs){
  7.         this.bomService = bs;
  8.     }

  9.     public  void methodA()

  10.     {

  11.         bomService.methodB();   



  12.     }







  13. }
复制代码
回复

使用道具 举报

 楼主| 发表于 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都可以用。
回复

使用道具 举报

Follow Us
发表于 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 编辑 ]
回复

使用道具 举报


ADVERTISEMENT

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 18-12-2025 01:51 AM , Processed in 0.129514 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表