So, what you can do is have the Order link to a Sessions table - to indicate in which session the order was created.
JSecurity supports this scenario too - you can set a SessionDAO implementation on the SecurityManager so calls to subject.getSession() returns a Session implementation that talks to your database. But since sessions are in the database - you _really_ want to think about using a distributed/clustered cache like TerraCotta or Coherence. Constant serialization of Session objects to/from a Sessions RDBMS table is the least performant mechanism, so you'd want that cache enabled. JSecurity supports this too ;) (securityManager.setCacheManager(...)). Cheers, Les On Tue, Sep 23, 2008 at 2:56 PM, Animesh Jain <[EMAIL PROTECTED]> wrote: > Hmm.. well yeah I guess its not too difficult to save to the session. But if > you think of it in a little more detail it can get tricky in certain > situations. Just for an eg. lets say we delete a product, or it goes out of > stock or something. If things are in the db then I can make changes across > the application. This is just an example, maybe not good enough to get my > point across, but I hope you can see what i mean :). I can think of a few > other situations (specific to my usecase) where things will really start > making all the session handling messy. > > I'm still thinking, still not convinced with any solution so far. I guess > this is outside jsecurity anyway. > > Cheers > Animesh > > On Wed, Sep 24, 2008 at 12:12 AM, Les Hazlewood <[EMAIL PROTECTED]> wrote: >> >> Its _much_ easier to put it in the session ;) >> >> subject.getSession().putAttribute( "currentOrder", shoppingOrder ); >> >> Then you pull it out after they've created an account. >> >> It would only make sense to store it in a table if it is persistent >> beyond the life of the user's session. But, keying it off of session >> id won't work - if their session expires and they come back tomorrow, >> they'll have a new session ID, and the old order would be lost. It >> would effectively be an orphan at that point and you'd need a nightly >> task (e.g. via Quartz) to delete those orphans. If you want it to be >> persistent across sessions and they're not a user (a guest), then >> serialize the order into a cookie. JSecurity does this for identity >> serialization for RememberMe. Check out the WebRememberMeManager >> implementation for ideas: >> >> >> http://jsecurity.svn.sourceforge.net/viewvc/jsecurity/trunk/src/org/jsecurity/web/WebRememberMeManager.java?revision=886&view=markup >> >> Cheers, >> >> Les >> >> On Tue, Sep 23, 2008 at 2:34 PM, Animesh Jain <[EMAIL PROTECTED]> >> wrote: >> > oops.. i meant authc too. >> > >> > well thats actually what i was trying to avoid. here I'll have to write >> > separate logic to handle all that data in the session. might as well be >> > a >> > separate order table with session id in place of user id. Or is it >> > easier to >> > do the handling in session than I'm imagining? >> > >> > Cheers >> > Animesh >> > >> > On Tue, Sep 23, 2008 at 11:50 PM, Les Hazlewood <[EMAIL PROTECTED]> >> > wrote: >> >> >> >> Hi Animesh, >> >> >> >> (just a quick clarification - we use the abbreviation 'authc' for >> >> AuthentiCation (identity verification and login) - and 'authz' for >> >> AuthoriZation (access control - roles, perm checks). >> >> >> >> Anyway - on to the question. >> >> >> >> In my commerce applications, a user has one or more Orders. You can >> >> think of an Order as a ShoppingCart if you like, but I call it an >> >> Order because it will actually be inserted into the database - >> >> ShoppingCarts are usually thought of as temporal by nature - i.e. they >> >> often 'expire' after the user logs out or their session expires. >> >> >> >> My Order objects have the following attributes (slightly simplified >> >> for this example): >> >> >> >> - User user - the user responsible for creating/initiating the order. >> >> - Date creationTimestamp - when the selects their very first item, an >> >> order is created. >> >> - Amount subtotal - the total of all the order line items. An Amount >> >> object holds 3 things: A currency indicator and a BigDecimal. >> >> BigDecimal is used to ensure accuracy is retained during currency >> >> conversion so money is not lost (i.e. a double wouldn't be a good >> >> choice to represent monetary values). >> >> - Amount total - the total amount the user owes (includes the subtotal >> >> plus any taxes and shipping and handling). >> >> - List<LineItem> - all the line items in the order. A LineItem >> >> contains 3 things: a Product reference (what they are buying), an >> >> Amount - what the price is of the product at the time their selection >> >> goes into the order (important!), and an int quantity - how many of >> >> those products at that price they're ordering in the current order. >> >> - OrderState state - an ENUM representing the current state the order >> >> can be in - open (i.e. new or continued), paid, shipped, received, >> >> etc. - whatever your domain needs. >> >> and a List<Payment> - all the payments associated with the order. >> >> Most orders will have a single payment equal to the Order total, but I >> >> model it this way to handle edge cases in my domain logic. Anyway, >> >> moving on... >> >> >> >> So, how do I handle the scenario of user vs. non user shopping? >> >> >> >> If they are a User, the order immediately gets placed in the database >> >> table as soon as it is created (i.e. they select their first item to >> >> put in the 'cart' - the Order). The Order table has a User reference >> >> that records who is 'building' the order. The User property is >> >> non-null for that table, ensuring that all orders are attributed to a >> >> User. The interesting thing about this is that a User can have one or >> >> more open orders - think of any Order that is not their latest >> >> (current) one as a 'wish list' order that they can resolve when they >> >> want. >> >> >> >> If they are *not* a User, that is, a guest, the Order object gets >> >> attached to their session. When they check out, they must first >> >> create a user account (which amounts to usually just an email address >> >> and password). After that is done, the Order attached to their >> >> session gets added to the Orders table since there is now a User to >> >> associate it with. Before they become a User, you can can also >> >> serialize their Order to a Cookie so if that person does not check out >> >> (meaning they won't become a User yet), then at least the order is >> >> there for reconstitution when they come back to the site and they can >> >> keep shopping with it. >> >> >> >> You can check to see if they are a 'User' in JSecurity by checking: >> >> >> >> if ( subject.getPrincipal() != null ) { >> >> // they are a User because a principal is an identifying attribute, >> >> // and you only have an identity if you have an account >> >> } >> >> >> >> Similarly, you can check if they are a 'guest': >> >> if ( subject.getPrincipal() == null ) { >> >> // guest user, attach to session >> >> } >> >> >> >> I hope that helps a little. Feel free to ask more questions ;) >> >> >> >> Cheers, >> >> >> >> Les >> >> >> >> On Tue, Sep 23, 2008 at 2:22 AM, Animesh Jain <[EMAIL PROTECTED]> >> >> wrote: >> >> > Hi >> >> > >> >> > This is more of a best practice question. I would like to know >> >> > recommendations on how to handle guest users in a webapp. Lets say I >> >> > have an >> >> > ecommerce store, where a user is allowed to shop around and add items >> >> > to >> >> > shopping cart without logging in (authz). Now how should I maintain >> >> > the >> >> > data >> >> > this user generates. In my one of my current apps I have a separate >> >> > temp_user table but it ofcourse makes things messy in the sense now >> >> > my >> >> > order >> >> > table has two types of users, one for orders with logged in users and >> >> > one >> >> > for users who are not logged in. >> >> > >> >> > Should we instead have just one single user table and create an entry >> >> > for a >> >> > guest user in it whenever required. For eg lets say when a user adds >> >> > something to the shopping cart then we just create a user entry for >> >> > this >> >> > user in the background with a guest role and log him in and then >> >> > proceed >> >> > with the action. How could this logic be possibly centralized. For eg >> >> > there >> >> > may still be certain actions that require a higher role. For eg we >> >> > may >> >> > want >> >> > payments to be made only after signups. Any suggestions? Also >> >> > wouldn't >> >> > this >> >> > add a lot of temporary user rows to the user table ? >> >> > >> >> > Thanks in advance >> >> > Animesh >> >> > >> >> > >> > >> > > >
