Hey Brian, Short answer, google stripernate and typeconversion, long answer below. (beware, this is detailed, but it's not difficult. It may seem like a bit of work upfront, but it's all straight forward code with no real trickery involved) Don't be scared of the length here, stripes is really nice to work with and this is actually a pretty complex situation if you think about, but the solution is elegant (I think) and works well.
Long answer, yes, that is a different problem then I thought you were asking the first time. What's happening is pretty simple; your object has those relationships in the database, but your form doesn't know anything about them. It simply knows what is in the form, it doesn't know you have a complex object behind the scenes with other relationships. There are several ways to attack this (none are that hard mind you). The basic idea behind the way to fix this is to tell stripes to load the object first, and then before binding (populate object from form values) and validation. So where you have the user being loaded simply on the first call, that will get you all the form values populated, but it will not save the rest of the objects state for later use. Everything in a bean goes away between calls. So, to fix it you need to load the object every time you want to refer too it! You can do this several ways. The easiest way (and I would say 'incorrect' way), that would work for just this actionbean is to use @Before annotation on a method and load the user up by putting a hidden value on the form called userId or something and pulling it out of the request parameters: um.load(Long.valueOf(context.getRequest().getParameter('userId')) //or something similar This isn't elegant, convenient, or robust, you can probably see several reasons why. The next way involves several key areas of stripes. First is the automatic extension lookup for stripes; Extensions and using that to supply your own converter for your persisted classes: TypeConverters. Now, you could make a type converter for each of your @Entity classes, but that's almost as bad as the above solution, but not as bad and it's easy to add more classes. Stripes however should find them automatically and use them, so it's a step closer to a good solution. But, for a generic approach, that catches all the entities, here's my logic: First you need to make a generic EntityConverter to load any persistent object. Your converter needs access to something from your persistance layer, for example hibernate needs a SessionManager. This is tricky in 1.5, but believe is solved in 1.6. Short of it is you need to use @SpringBean and modify the TypeConverterFactory to inject springbeans automatically (details below). Here's my entire converter : public class EntityConverter implements TypeConverter<Object>{ Locale locale; @SpringBean("sessionFactory") private SessionFactory sessionFactory; public void setLocale(Locale locale) { this.locale = locale; } public Object convert(String input, Class<? extends Object> targetType, Collection<ValidationError> errors) { if(input != null && !"null".equals(input) && !("0".equals(input)) && targetType.isAnnotationPresent(Entity.class)){ return sessionFactory.getCurrentSession().load(targetType, Long.parseLong(input)); }else{ return null; } } } To go with this you also need your own TypeConverterFactory. I extend the default and override two methods; getInstance and init In init() I use hibernates metadata to register all my entity classes to use the entity converter The getInstance method is need for the bit of hackery that goes away in future version of stripes: TypeConverter tc = super.getInstance(convertClass, locale); SpringHelper.injectBeans(tc, getConfiguration().getServletContext()); return tc; This simply lets your type converters use @SpringBean and have them populated correctly as they are not managed by spring or within the typical lifecycle for stripes. Assuming you have configured your stripes extensions package and the ConvertFactory lives in there it should find it automatically and start using it. Now, how does all this fix your problem?? :) You can now pass object ID values right along and stripes will automatically convert and load your entities, so your call to um.getUser("id") is no longer needed, instead user would be passed in as a parameter: /register?user=123 and it should get loaded automatically. For your wizard forms, you add a hidden value saying which user you are working; <s:hidden name="user" value="myid"/> This will get passed along and your user will appear as it should for every request. This will work for any of your objects coming from anywhere as long it's saved and a valid id is passed in your object will get 'hydrated' before the form values are saved to it and you will see all the values you will expect. Essentially after the setup is done this becomes transparent for the rest of the app. Hope this helps some and doesn't scare you away at all. :) -Nick On Apr 20, 2010, at 8:01 PM, Brian wrote: > Thanks again Nick for all your help. Unfortunately after trying your > suggestion of adding the taglib it still doesn't work. This should be simple. > The problem is that the object that I'm loading at the start of the wizard > has nested pre-populated relationships...eg, a User has a Zipcode. It's these > nested relationships and any other fields not on the page that seem to get > dropped from step to step. Ideally what I would have hoped would work is that > the User object would get populated at the start and only any changes would > get submitted through the wizard, the original values that are not affected > would stay the same. Unfortunately this doesn't seem to be the way it works > at all. > > Anyone else got any ideas? I would have really thought it's a pretty common > use case. > > Thanks again, > Brian > > On 20 Apr 2010, at 22:15, Nick Stuart <nstu...@speranzasystems.com> wrote: > >> You're right, just reading the docs on the Wizard Form page it doesn't >> mention it, but I've always used the tag when doing some simple wizard >> forms. You can find the documentation for the tag at: stripes:wizard-fields >> >> Also reading the wizard forms it references the bugzooky example which I >> know, unless it has change recently, is out of date so isn't always the best >> to go by. From reading the docs it seems like the @Wizard tag and >> stripes:form tag should auto-magically figure out that it's a part of a >> wizard and add the fields to the page. Check out the rendered page and see >> if there are a bunch of hidden fields on it from the first form (there >> should be!). The tag above should forcefully put them there if the magic >> isn't happening. >> >> Again, I'm not terribly sure it does, or SHOULD, happen automatically, as I >> always use the tag. Any other stripers have ideas here? >> >> -Nick >> >> On Apr 20, 2010, at 4:50 PM, Brian McSweeney wrote: >> >>> Hi Nick, >>> >>> thanks a million for the reply. I don't see anything about that in the docs >>> on the site... >>> >>> http://www.stripesframework.org/display/stripes/Wizard+Forms >>> >>> could you tell me where I can find better info about wizards in here? >>> >>> cheers, >>> Brian >>> >>> >>> On Tue, Apr 20, 2010 at 8:54 PM, Nick Stuart <nstu...@speranzasystems.com> >>> wrote: >>> Do you the the <s:wizardFields/> tag in the form for step 2? (forgive me if >>> it's not the correct name, but it's something like that). >>> >>> Thats key for the wizard to work correctly... >>> >>> -Nick >>> On Apr 20, 2010, at 2:59 PM, brian.mcswee...@gmail.com wrote: >>> >>> > Hi guys, >>> > >>> > I'm new to stripes and I'm trying to do what should be super easy. I'm >>> > trying to use a multipage wizard to edit an existing object. >>> > This must be a pretty regular pattern. I've tried using startEvent and >>> > saving the user that is retrieved from the database as follows. >>> > However the values of "user" don't get persisted between steps in the >>> > wizard...i've searched at length on the forums and found another >>> > relevant entry that was never answered.... >>> > >>> > http://www.mail-archive.com/stripes-users@lists.sourceforge.net/msg02020.html >>> > >>> > this should be simple surely, I'm new to stripes and want to give it a >>> > proper go...but already not being able to do this is worrying... >>> > >>> > thanks for any help, my code is below >>> > >>> > brian >>> > >>> > @Wizard(startEvents="begin") >>> > @UrlBinding("/register") >>> > public class RegisterActionBean extends BaseActionBean { >>> > >>> > protected final Log log = LogFactory.getLog(getClass()); >>> > private UserManager um; >>> > >>> > /** Setter to allow the UserManager to be injected. */ >>> > @SpringBean >>> > protected void setUserManager(UserManager um) { >>> > this.um = um; >>> > } >>> > >>> > @ValidateNestedProperties({ >>> > @Validate(field="password", required=true, >>> > minlength=5,maxlength=20,expression="${this eq confirmPassword}") >>> > }) >>> > private User user; >>> > private String confirmPassword; >>> > >>> > /* Getters and setters for user and confirmPassword */ >>> > @DontValidate >>> > @DefaultHandler >>> > public Resolution begin() { >>> > // for the moment just get one user from the database >>> > User user = (User)um.getUser("123"); >>> > this.setUser(user); >>> > return new ForwardResolution("/WEB-INF/jsps/edit1.jsp"); >>> > >>> > } >>> > >>> > public Resolution gotoStep2() throws Exception { >>> > // do some more logic here if necessary >>> > return new ForwardResolution("/WEB-INF/jsps/edit2.jsp"); >>> > } >>> > >>> > public Resolution gotoStep3() throws Exception { >>> > // do some more logic here if necessary >>> > um.save(user); >>> > return new ForwardResolution("/WEB-INF/jsps/editsuccess.jsp"); >>> > }------------------------------------------------------------------------------ >>> > _______________________________________________ >>> > Stripes-users mailing list >>> > Stripes-users@lists.sourceforge.net >>> > https://lists.sourceforge.net/lists/listinfo/stripes-users >>> >>> >>> ------------------------------------------------------------------------------ >>> >>> _______________________________________________ >>> Stripes-users mailing list >>> Stripes-users@lists.sourceforge.net >>> https://lists.sourceforge.net/lists/listinfo/stripes-users >>> >>> >>> >>> >>> -- >>> ----------------------------------------- >>> Brian McSweeney >>> >>> Technology Director >>> Smarter Technology >>> web: http://www.smarter.ie >>> phone: +353868578212 >>> ----------------------------------------- >>> >>> ------------------------------------------------------------------------------ >>> _______________________________________________ >>> Stripes-users mailing list >>> Stripes-users@lists.sourceforge.net >>> https://lists.sourceforge.net/lists/listinfo/stripes-users >> >> ------------------------------------------------------------------------------ >> _______________________________________________ >> Stripes-users mailing list >> Stripes-users@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/stripes-users > ------------------------------------------------------------------------------ > _______________________________________________ > Stripes-users mailing list > Stripes-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/stripes-users
smime.p7s
Description: S/MIME cryptographic signature
------------------------------------------------------------------------------
_______________________________________________ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users