playframework / play-plugins

CachePlugin
444 stars 161 forks source link

Handle the JedisPool separately from SedisPool #152

Closed rmmeans closed 9 years ago

rmmeans commented 9 years ago

Fixes #149

rmmeans commented 9 years ago

Once this is merged, I'll have another PR to submit to fix #153. If you'd rather, we can close this PR and submit it as one PR resolving both issues.

johdah commented 9 years ago

The line jedisPool.getResource(); still give me a null pointer exception.

package models;

...
import javax.inject.Inject;
import redis.clients.jedis.*;

@Entity
@Table(name="Account")
public class User extends AbstractModel implements Subject {
    @Transient
    @Inject JedisPool jedisPool; // The JedisPool will be injected for you from the Redis module

    ...

    public DateTime getLastAccessFromUser() {
        Jedis j = jedisPool.getResource();
        DateTime dateTime = null;

        try {
            String dtString = j.hget("userLastAccess", this.id.toString());
            dateTime = new DateTime(Long.valueOf(dtString));
        } catch(NumberFormatException ex) {
            dateTime = null;
        } finally {
            jedisPool.returnResource(j);
        }

        return dateTime;
    }
}
rmmeans commented 9 years ago

Please make sure you are using version 2.4.1 of the module. I wrote a simple Java play app this morning to verify that it works and had no problems with this. I was connected to the redis env using a monitor command and could see all the gets and sets coming through without problems.

package controllers;

import play.mvc.Controller;
import play.mvc.Result;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.inject.Inject;
import java.util.UUID;

public class HelloRedis extends Controller {

    @Inject
    private JedisPool pool;

    public Result redisHello() {
        Jedis j = pool.getResource();
        String randomStringFromRedis = null;
        try {
            j.set("test", UUID.randomUUID().toString());
            randomStringFromRedis = j.get("test");
        } finally {
            pool.returnResource(j);
        }

        return ok(randomStringFromRedis);
    }
}
johdah commented 9 years ago

I have verified that it is 2.4.1. That I use it inside a model shouldn't be a problem right?

johdah commented 9 years ago

I managed to get it to work in the controller so I guess the problem has to do with either:

I guess I could rewrite the code to move this to the controller but I would rather like to have it separated from the controllers.

johdah commented 9 years ago

I tried to move it to my DAO to see if the @Transient annotation was the problem but I still get a null value.

...

import javax.inject.Inject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class UserDAO extends AbstractDAO<User, User_> {
    @Inject JedisPool jedisPool;

    public UserDAO() {
        super(User.class, User_.class);
    }

    /**
     * @return an instance of {@link UserDAO}.
     */
    public static UserDAO newInstance() {
        return new UserDAO();
    }

    ...

    // -- Redis

    /**
     * Get the last time the user accessed the service.
     *
     * @param user the {@link models.User}
     * @return the last time as a {@link org.joda.time.DateTime}
     */
    public DateTime getLastAccess(User user) {
        if(jedisPool == null) {
            Logger.error("Redis is not available");
            return null;
        }

        Jedis j = jedisPool.getResource();
        DateTime dateTime = null;

        try {
            String dtString = j.hget("userLastAccess", user.id.toString());
            dateTime = new DateTime(Long.valueOf(dtString));
        } catch(NumberFormatException ex) {
            dateTime = null;
        } finally {
            jedisPool.returnResource(j);
        }

        return dateTime;
    }
}