Search code examples
javadatabaselistjdopersistent

Persistent list in JDO (Google App Engine)


I`m developing the server side for a mobile app with Google App Engine and JDO in Java, and I have some problems saving objects list in the database.

I have a one-to-many relationship between conversation and messages (I`m trying to do a chat-like application). A conversation has a list of messages and a message belongs to a conversation. When I do makePersistent of a conversation, if I get the same conversation with the ID, all is fine and the list is returned with the messages. But if I close that instance of the PersistenceManager and I try to get the conversation in another method, the conversation is all fine (the attributes like hour, idUser, etc), except for the list of messages which is null. No matter what changes I do, that list is always null.

Here is my code:

Conversation.java:

import java.util.LinkedList;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION)  
public class Conversation 
{
    @PrimaryKey  
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)  
    private Long id;

    @Persistent
    private Long idUser;

    @Persistent(mappedBy = "conversation")
    private LinkedList<Message> messages;

    public Conversation(Long idUser) 
    {
        this.idUser = idUser;

        messages = new LinkedList<Message>();       
    }

    public Long getId() {
        return id;
    }

    public Long getIdUser() {
        return idUser;
    }

    public LinkedList<Message> getMessages() {
        return messages;
    }
}

Message.java:

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.datastore.Key;

@PersistenceCapable(identityType = IdentityType.APPLICATION)  
public class Message 
{
    @PrimaryKey  
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)  
    private Key id;

    @Persistent
    private Conversation conversation;

    @Persistent
    private String text;

    @Persistent
    private String hour;

    public Message(String text, String hour)
    {
        this.text = text;
        this.hour = hour;
    }

    public String getText() 
    {
        return text;
    }

    public String getHour() 
    {
        return hour;
    }

    public Key getId() 
    {
        return id;
    }

    public Conversation getConversation() {
        return conversation;
    }
}

Besides I have tried to get the messages separately and I successfully get them. The messages are saving well, but the list of them in conversation is missing.

I hope someone can help me, thanks in advance!

EDIT: I save the conversation after I add the messages with this code:

final PersistenceManager persistenceManager = PMF.get().getPersistenceManager();      
final Conversation conversation = new Conversation(idUser1, idUser2);

//Add the messages successfully

try 
{
    persistenceManager.makePersistent(conversation);
} finally {
    persistenceManager.close();
}

And I get the conversation with that one:

final PersistenceManager persistenceManager = PMF.get().getPersistenceManager();  
Long idConversation;

//Got the idConversation with a query successfully

Conversation conversation = persistenceManager.getObjectById(Conversation.class, idConversation);
return conversation;

Solution

  • You don't state how you retrieve the object from the datastore, and where you access the List. Within a transaction? Outside a transaction ? what state is the object in ? hollow? detached? Is the List in the current fetch group when you retrieve the owning object?

    Put the list in the current fetch group.