Question

I've written a task manager, and well it;'s a long story... all in Java by the way. So I wrote a Facade which you can see below there is a problem with the HashMap and I suspect that the values which I attempt to add into the HashMap during the construction aren't going so well. The method that is triggering the null pointer exception is the create method. the input parameters to the method have been verified by me and my trusty debugger to be populated.

any help here would be great... I'm sure I forgot to mention something so I'll reply to comments asap as I need to get this thing done now.

package persistence;

import java.util.UUID;
import java.util.HashMap;

import persistence.framework.ComplexTaskRDBMapper;
import persistence.framework.IMapper;
import persistence.framework.RepeatingTaskRDBMapper;
import persistence.framework.SingleTaskRDBMapper;

public class PersistanceFacade {

    @SuppressWarnings("unchecked")
    private static Class SingleTask;
    @SuppressWarnings("unchecked")
    private static Class RepeatingTask;
    @SuppressWarnings("unchecked")
    private static Class ComplexTask;

    private static PersistanceFacade uniqueInstance = null;
    @SuppressWarnings("unchecked")
    private HashMap<Class, IMapper> mappers;

    public PersistanceFacade() {
        mappers = new HashMap<Class, IMapper>();
        try {
            SingleTask = Class.forName("SingleTask");
            RepeatingTask = Class.forName("RepeatingTask");
            ComplexTask = Class.forName("ComplexTask");
            mappers.put(SingleTask, new SingleTaskRDBMapper());
            mappers.put(RepeatingTask, new RepeatingTaskRDBMapper());
            mappers.put(ComplexTask, new ComplexTaskRDBMapper());
        }
        catch (ClassNotFoundException e) {}

    }

    public static synchronized PersistanceFacade getUniqueInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new PersistanceFacade();
            return uniqueInstance;
        }
        else return uniqueInstance;
    }

    public void create(UUID oid, Object obj) {
        IMapper mapper = (IMapper) mappers.get(obj.getClass());
        mapper.create(oid, obj);
    }

    @SuppressWarnings("unchecked")
    public Object read(UUID oid, Class type) {
        IMapper mapper = (IMapper) mappers.get(type);
        return mapper.read(oid);
    }

    public void update(UUID oid, Object obj) {
        IMapper mapper = (IMapper) mappers.get(obj.getClass());
        mapper.update(oid, obj);
    }

    @SuppressWarnings("unchecked")
    public void destroy(UUID oid, Class type) {
        IMapper mapper = (IMapper) mappers.get(type);
        mapper.destroy(oid);
    }


}
Was it helpful?

Solution

My guess is that your problem lies in the constructor:

    try {
        SingleTask = Class.forName("SingleTask");
        RepeatingTask = Class.forName("RepeatingTask");
        ComplexTask = Class.forName("ComplexTask");
        mappers.put(SingleTask, new SingleTaskRDBMapper());
        mappers.put(RepeatingTask, new RepeatingTaskRDBMapper());
        mappers.put(ComplexTask, new ComplexTaskRDBMapper());
    }
    catch (ClassNotFoundException e) {}

You silently ignore the ClassNotFOundException. If you add logging to the catch I expect it to tell you that the class SingleTask is not found, as I expect that you did not put those classes in the default package.

Given your reply to comments these classes are in the domain. package, so you could try to change to:

    try {
        SingleTask = Class.forName("domain.SingleTask");
        RepeatingTask = Class.forName("domain.RepeatingTask");
        ComplexTask = Class.forName("domain.ComplexTask");
        mappers.put(SingleTask, new SingleTaskRDBMapper());
        mappers.put(RepeatingTask, new RepeatingTaskRDBMapper());
        mappers.put(ComplexTask, new ComplexTaskRDBMapper());
    }
    catch (ClassNotFoundException e) {
        log.warn("Cannot load class", e);
    }

Btw, adding logging to your code will help to find the reasons behind unexpected behaviour.

OTHER TIPS

For Class.forName("RepeatingTask") to return a class you must have a class persistence.RepeatingTask. But in your comment you say that obj.getClass() returns domain.RepeatingTask so it looks to me like you have 2 "RepeatingTask" classes or domain.RepeatingTask is a sub type.

Class.forName("SingleTask"); is throwing a ClassCastException, so mappers does not get populated. Since you are ignoring ClassCastExeption in your constructor you have missed that error, it seems.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top