3

I'm trying to implement a quiz application. The application loads the questions with ajax one by one. When a user clicks the 'to next question' button his/her answer is saved in cache. But when I debug, cache list is always null...

This code creates the first cache array:

public static void viewQuiz(@Required String user, @Required String test) {        
        if(validation.hasErrors()) {
            flash.error("Hoop kullanıcı lazım…");
            index();
        } else{
            TestClass selectedTest = TestClass.find("title", test).first();
            List<String> choiceList = new ArrayList<String>();
            session.put("testID", selectedTest.id);
            Cache.set("choices", choiceList, "30mn");
            render();
        }
    }

And this code is trying to save the answers one by one:

public static void question(@Required Long id, String answer){
    Long testId = Long.parseLong(session.get("testID"));
    TestClass test = TestClass.findById(testId);
    List<Question> questList = Question.find("test_id", test.id.intValue()).fetch(); 
    Question quest = questList.get(id.intValue());
    if(answer != null){
        List<String> choiceList= Cache.get("choices",List.class);
        choiceList.add(id.intValue(), answer);
        Cache.set("choices", choiceList, "30mn");
    }   
    int count = questList.size()-1; 
    render(quest, count, id);
}

And this code is the html view of the second:

 #{extends 'main.html' /}

#{set title:'question.html' /}

<script type="text/javascript"> 
        var questionId = ${id};
        $('#nextButton').click(function(){
        $('#questionDiv').html('<p><img id = "loaderGif" src="public/images/loading.gif"/></p>');

        $('#questionDiv').load("/test/" + ++questionId);

    });
    $('#endButton').click(function(){
        $('#questionDiv').html('<p><img id = "loaderGif" src="public/images/loading.gif"/></p>');
        $('#questionDiv').load("/result");
    });
 </script> 

<legend>Soru ${id+1}</legend>
<p>&{quest.question}</p>

#{list items:quest.choices, as:'choice'} 
<p><input type="radio" name = "answer" id = "answer" size="30" value="${choice}"/>&{choice}</p>
#{/list}
#{if id < count}
<input id = "nextButton" name="nextButton" type="button" value="İleri"/>
#{/if}
#{else}
<input id = "endButton" name="endButton" type="button" value="Bitti"/>
#{/else}
Jasper
  • 2,166
  • 4
  • 30
  • 50
Ömer Faruk AK
  • 2,409
  • 5
  • 26
  • 47
  • What version of Play are you using? Are you using the standard in-memory cache, or are you using something else, like memcache. I am also assuming that you are on a single server as it is Dev mode, and not load balancing across multiple instances. – Codemwnci Jul 18 '11 at 12:32
  • 1
    I should also note, as Play is stateless, you should not use the Cache as a data store. If you are load balancing, there is no guarantee that you will return to the same server. By keeping things in memory, you are breaking the stateless nature of Play. The cache is best used when data already exists in the database, but is being used to minimise frequent database reads.# – Codemwnci Jul 18 '11 at 12:33
  • I'm trying to learn play. I'm using play 1.2.1 and do not change any cache settings. I'm on ubuntu localhost with mysql. – Ömer Faruk AK Jul 18 '11 at 12:37

2 Answers2

13

Don't use the cache to 'store' objects. Either store it in the session or create a new model to store the answers. Generally, you cannot expect the cache to retain the objects you put into; it's a cache, not a store.

To quote from the Play! website: http://www.playframework.org/documentation/1.2.2/cache

It is important to understand that the cache contract is clear: when you put data in a cache, you can’t expect that data to remain there forever. In fact you shouldn’t. A cache is fast, but values expire, and the cache generally exists only in memory (without persistent backup).

2

Cache is not reliable and you may get it as null in dev mode. This is expected and you can try changing it to prod mode and see its behavior.

sojin
  • 4,527
  • 2
  • 37
  • 40