Whoops, sorry; ignore my remark about UserStats not being persistable; I looked again at your code and saw that it has a key. I was confused and thinking that you're persisting the List, not an item in the List. But I think the problem with it becoming a root object still remains.
Rusty Wright wrote: > 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)" <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en -~----------~----~----~----~------~----~------~--~---
