空指针异常,因为memberCache为空

时间:2019-09-17 04:31:12

标签: java nullpointerexception

我不是在这里问什么是空指针异常。我已经调试了项目并看到了空指针在哪里。我的项目流程是:

enter image description here

我的Api是:

package com.cache.api;

@Path("/myresource")
public class MyResource  {

    @Inject
    private CacheHelper cacheHelper;

    @Inject
    private DtoPlan dtoPlan;

    @GET
    @Path("/putAllInDto")
    @Produces(MediaType.APPLICATION_JSON)
    public String putAllInDto() throws Exception {

       CachePlan cf=CacheFactory.getPlan(PlanChooser.DTO);
       cf.putInCache(); //data are loaded in DtoPlanImpl Class

        MemberDTO md=cf.getMemberDtos();  //data comes from here with cf object

    //    MemberDTO md1=dtoPlan.getMemberDto();  //java.lang.NullPointerException when I use dtoPlan.memberDto();

//
//        System.out.println(md.getMemberName());
        return "insertedindto";
    }


}

cachePlan接口为:

package com.cache.plan;

    public interface CachePlan {

        public  void putInCache() throws ExecutionException, InterruptedException ;

        public MemberDTO getMemberDtos() throws ExecutionException, InterruptedException ;

        }

我的DtoPlanImpl.java类是。这里我需要实现新的接口 DtoPlan

package com.cache.impl;


    @Stateless
    public class DtoPlanImpl implements CachePlan,DtoPlan
    {

        private CacheManager cacheManager;

        private Cache<String,MemberDTO> memberCache;

        private static final String CACHE_MEMBER_DTO_PARAMETER="cache_member_dto_type";

        private MemberService memberService = CDI.current().select(MemberService.class).get();


        public DtoPlanImpl(){
            System.getProperties().setProperty("java -Dnet.sf.ehcache.use.classic.lru", "true");
            cacheManager= CacheManagerBuilder
                    .newCacheManagerBuilder().build();
            cacheManager.init();
        }


        @Override
        public void putInCache()  {
            System.out.println("putting data from dto");

            memberCache = cacheManager
                    .createCache("cacheOfMemberCache", CacheConfigurationBuilder
                            .newCacheConfigurationBuilder(
                                    String.class,MemberDTO.class,
                                    ResourcePoolsBuilder.heap(1000000000)).withExpiry(Expirations.timeToLiveExpiration
                                    (Duration.of(60000,
                                    TimeUnit.SECONDS))));

            memberCache.put(CACHE_MEMBER_DTO_PARAMETER,memberService.getMemberDTO());

            MemberDTO mD=memberCache.get(CACHE_MEMBER_DTO_PARAMETER);
            System.out.println(mD.getMemberName());

         }

        @Override
        public MemberDTO getMemberDtos() {
            MemberDTO mD=memberCache.get(CACHE_MEMBER_DTO_PARAMETER);
            return mD;
        }


        @Override
        public MemberDTO getMemberDto() throws ExecutionException, InterruptedException {
            MemberDTO mD=memberCache.get(CACHE_MEMBER_DTO_PARAMETER);
             return mD;
        }


    }

我的DtoPlan界面是:

public interface DtoPlan {

    public MemberDTO getMemberDto() throws ExecutionException, InterruptedException;


}

所以问题是当我将CacheFactory cf用作:

MemberDTO md=cf.getMemberDtos();  //data comes from here with cf object

但是当我使用时:

 MemberDTO md1=dtoPlan.getMemberDto();  //java.lang.NullPointerException 

我调试了程序,并从出现空指针的地方开始可视化: 它来自第MemberDTO mD=memberCache.get(CACHE_MEMBER_DTO_PARAMETER);行的此类DtoPlanImpl:

@Override
    public MemberDTO getMemberDto() throws ExecutionException, InterruptedException {
        MemberDTO mD=memberCache.get(CACHE_MEMBER_DTO_PARAMETER);
         return mD;
    }

在这里我从dtoPlan.getMemberDto();调用的memberCache为null,但是当我从cf.getMemberDtos();调用时,我正在获取数据。

1 个答案:

答案 0 :(得分:0)

您正在memberCache方法中初始化putInCache(),而不是在构造函数中初始化。对于您的设计,您需要先将某些内容放入缓存中,然后才能检索某些内容。因此,可以在构造函数中对其进行初始化,也可以在其中 put

还要注意,默认情况下,Guice每次提供值时都会返回一个新实例。因此,您可能在将内容放入缓存中时使用一个实例,从而初始化memberCache,而在检索数据时使用另一个实例,其中memberCache为空。您可以使用@Singleton注解在所有地方注入DtoPlan的相同实例。

看起来您每次需要在其中添加新内容时都在创建一个新的缓存实例。因此,您将丢失先前存储的值。整个代码看起来有缺陷。