1) In the case of result.isEmpty(), I don't see where you're adding the new 
UserStats to the result list.

2) When you do pm.makePersistent( stats ) I think you're going to have a 
problem adding the new stats to the List<UserStats>, because that 
makePersistent is going make a new stats a root/parent object.  But then I 
don't see how you can do a makePersistent on stats since it doesn't have a Key 
field; I thought you can/should only call makePersistent on objects that have a 
primary key field (your classes, annotated with @PersistenceCapable).

3) Constructing queries with string concatenation like that is a security hole, 
an invitation to sql injection attacks.  Use parameters.  http://xrl.in/3i9x

4) I'm wondering if you're approaching this thinking about things the "old" 
relational database way, with tables.  Instead, map out your domain objects as 
java objects, and don't think about tables at all.  Wipe sql tables from your 
mind when using Google App Engine.  Use pencil and paper and draw diagrams 
showing what's inside of what or what needs what (for example, uml diagrams).  
Whenever you have an object that's not inside another object stop and analyze 
things and see if there is some way it could/should go inside another object; 
this can be hard at first if you're still thinking about tables and joins (I'm 
still figuring this out).  At the moment my thinking is that the only time you 
should have an object not be inside another object, *when you persist it* 
(whereupon it becomes a root object), is an object that moves around; sometimes 
it's in object A, sometimes object B, etc.  Then you have to store in the 
containing outer object the inner object's Key instead of th
e object.  For example, in your case, I'm wondering if instead of having a List 
of UserStats, have a List of User, and each user has a UserStats object in it.

I'm still trying to figure this out so I could be wrong about this.


barak wrote:
> Here it is:
> 
> PersistenceManager pm = PMF.get().getPersistenceManager();
> 
> List<UserStats> result = (List<UserStats>) pm.newQuery( "select from "
> + UserStats.class.getName() + " where id == '" + session.getId() +
> "'" ).execute();
> 
> if( result.isEmpty() )
>     stats = new UserStats( session.getId(), System.currentTimeMillis
> () );
> else
>     stats = result.get( 0 );
> 
> Integer counter = stats.getQueries().get( query );
> 
> if( counter == null )
>     counter = new Integer( 1 );
> else
>    counter = new Integer( counter.intValue() + 1 );
> 
> stats.getQueries().put( query, counter );
> 
> try
> {
>       pm.makePersistent( stats );
> }
> finally
> {
>       pm.close();
> }
> 
> On Oct 30, 8:47 pm, "Jason (Google)" <apija...@google.com> wrote:
>> Can you post the code that you're using to re-persist the updated HashMap?
>>
>> - Jason
>>
>>
>>
>> On Thu, Oct 29, 2009 at 6:07 AM, barak <barak.ya...@gmail.com> wrote:
>>
>>> Thanks, did that and the map is indeed serialized now. But now, the
>>> enitity is fetched, seems like the state is not always kept.
>>> For example, I would like to store some attribute from an HttpSession
>>> using the UserStats instance. Every time a user in a session press
>>> some button, a instance is fetched (using the session id as an
>>> identifier) and update a counter in the HashMap. The problem I faced
>>> is even that the object is found by the JDO, the counter updated and
>>> the object persisted again, next fetch does not return the instance
>>> with the updated counter. Can you help please debugging this?
>>> This is the data object:
>>> @PersistenceCapable(identityType = IdentityType.APPLICATION)
>>> public class UserStats
>>> {
>>>        @PrimaryKey
>>>        @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
>>>        private Key                                                     key;
>>>        @Persistent
>>>        private String                                          id;
>>>        @Persistent
>>>         private Long                                            time;
>>>        @Persistent( serialized ="true" )
>>>         private HashMap<String, Integer>        queries;
>>>         public UserStats( String id, Long time )
>>>        {
>>>                this.id = id;
>>>                this.time = time;
>>>                queries = new HashMap<String, Integer>();
>>>        }
>>>        public Key getKey()
>>>        {
>>>                return key;
>>>        }
>>>        public String getId()
>>>        {
>>>                return id;
>>>        }
>>>        public void setId( String id )
>>>        {
>>>                this.id = id;
>>>        }
>>>         public Long getTime()
>>>        {
>>>                return time;
>>>        }
>>>        public void setTime( Long time )
>>>        {
>>>                this.time = time;
>>>         }
>>>        public HashMap<String, Integer> getQueries()
>>>        {
>>>                return queries;
>>>        }
>>>        public void setQueries( HashMap<String, Integer> queries )
>>>        {
>>>                this.queries = queries;
>>>        }
>>> }
>>> On Oct 29, 10:38 am, Patrizio Munzi <patrizio.mu...@eris4.com> wrote:
>>>> HashMap isn't supported as a persistable type.
>>>> The only way you've got to persist it is serialize it:
>>> http://gae-java-persistence.blogspot.com/2009/10/serialized-fields.html
>>>> 1KViewDownload- Hide quoted text -
>> - Show quoted text -
> > 

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google App Engine for Java" group.
To post to this group, send email to google-appengine-java@googlegroups.com
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to