Additon, so that you can see that there is nothing hidden in the dao and bo layers which hides complexity:
dao: public User createUpdateUser(User user) { if(!getEm().contains(user) && user.getId() == null) getEm().persist(user); //we flush here because the user already exists //since we apply conversations here no merge is needed anymore getEm().flush(); return user; return null; } bo: @Transactional public User createUpdateUser(User user) { return userdao.createUpdateUser(user); } the bo weaves a transaction and calls the dao the dao flushes in edit cases and persists in create in case of a lost entity we bomb out with an exception and a roollback but i have yet to see that case. of course all this can be combined into one conversation like seam does it in its examples, but I opted for the dao bo pattern. Werner Punz schrieb: > Ok here is a first small bite: > > What we have here is a simple detail conversation > the master gets injected so that we can have work done > after update > but lives in its own conversation > > what happens the user id is injected so is the master > (design decision i chose, you probably could get > the affected dataset also from the master if you set it there, > but I wanted to have clear boundaries so i pushed in the uid of the user > and have it reloaded insted of merging it in. > > The entire time the form is open the conversation keeps the user and the > db connection > > now if you want to save it... > public String dosubmit() { > flushCurrentUser(); > > usermasterview.findUsers();//we refill our view dont access the > db objects there, different em > return StdOutcome.SUCCESS; > } > > > flushcurrentUser basically just goes into an entity manager flush > (the Entity Manager is injected by @PersistenceContext somewhere in the > bo layer automatically, fusion + spring takes care of that, > hence theoretically you could go for a seam like approach of injecting > the PersistenceContext directly into the conversation. > > anyway, em.flush that is it or em.persist in case of a create > all the time you work on the same user object coming from the entity > manager and having it referenced there. > > usermasterview.findUsers();// > > refills the master view with new data so that at a back > or go_master situation you have the updated data there > > once you are done > Conversation.getCurrentInstance().invalidate(); > return "go_master"; > > For simple navigational use cases you can invalidate all open > conversations at once, so that you do not have pending conversations. > If you still run into those, the conversations time out after while. > > > > > > public class UserDetailView { > UserBO userbo; > User user = new User(); > UserMasterView usermasterview; > > int userid; > boolean postinitialized = false; > String viewmode = "create"; > > > public int getUserid() { > return userid; > } > > > public void setUserid(int userid) { > this.userid = userid; > if(!postinitialized) { > postInitialize(userid); > } > } > > > > public void setPreinitUserid(int userid) { > postInitialize(userid); > } > public int getPreinitUserid() { > return -1; > } > > > public void postInitialize(int userid) { > postinitialized = true; > user = userbo.loadUserById(userid); > viewmode = "edit"; > } > > public String dosubmit() { > flushCurrentUser(); > > usermasterview.findUsers();//we refill our view dont access the > db objects there, different em > return StdOutcome.SUCCESS; > } > > public String dogomaster() { > Conversation.getCurrentInstance().invalidate(); > return "go_master"; > } > > > public void flushCurrentUser() { > userbo.createUpdateUser((User)user); > } > > > > public UserBO getUserbo() { > return userbo; > } > > public void setUserbo(UserBO userbo) { > this.userbo = userbo; > } > > > public User getUser() { > return user; > } > > public void setUser(User user) { > this.user = user; > } > > public String getViewmode() { > return viewmode; > } > > public void setViewmode(String viewmode) { > this.viewmode = viewmode; > } > > public UserMasterView getUsermasterview() { > return usermasterview; > } > > public void setUsermasterview(UserMasterView usermasterview) { > this.usermasterview = usermasterview; > } > > } > > > > Arash Rajaeeyan schrieb: >> how can I see the result of this work? >> >> On 2/27/07, *Werner Punz* <[EMAIL PROTECTED] >> <mailto:[EMAIL PROTECTED]>> wrote: >> >> Sorry to jump in here again, >> I have been playing guinea pig the last >> week for marios work. >> All I can say is this thing now is highly usable >> by now. >> You can put a view controller under conversation scope >> (not a shale one yet, you will lose the callbacks) >> and simply work on the stuff now like you would do in a rich client >> environment with an EntityManage, Hibernate Session open for the entire >> conversation. >> >> once you hit a point when you want to terminate, you can have the view >> controller/conversation invalidate itself or restart itself. >> >> Also binding component bindings onto such a conversation is taken care >> of, you can push them into a separate bean which you weave in by >> a scope of request and aop:scoped-proxy, then you basically get a fresh >> view onto your backend component bindings at every request. >> >> To sum it up, I just almost finished a first full master detail crud >> ( I have done several details forms before) >> The master form has about 30 lines of core code, excluding the setters >> and getters already dealting with dao calling, handling the query part >> etc... and adding a detail was a matter of one hour of figuring out >> which patterns work best and a few minutes of implementation >> handling new update and delete. >> The objects you work with always are the same the orm layer accesses, >> so a simple update ends up normally with >> >> entitymanager.flush (); >> >> And btw. bindings for hibernate and jpa already are in place... >> >> All I can say is a lot of thanks to mario for this, this is a killer... >> I think he has found the right mix of exposing the api and >> trying to automate. Seam while being excellent and Gavin was entirely >> correct with his approach of keeping the entitymanager open for a >> conversation, automates and hides way too much for my taste. >> One example is that it takes away the control how you connect >> the master and the detail, and in the end breaks the Tomahawk table >> that way. >> >> >> Gerald Müllan schrieb: >> > Mario, >> > >> > i am feeling very confident that this will be a great addition to >> > MyFaces in the near future. >> > >> > Through many lessons learned, I can admit that using Spring + JSF >> > together makes up a powerful combination. Tying the new >> > Spring/MyFaces-Conversation scope to JSF brings us beneath a >> > "seam-approach", but with less burden. I am quite curious about using >> > the sample-app! >> > >> > As i believe, the sandbox stuff will be removed, after fusion will be >> > quite stable. >> > >> > I also agree that it should have been discussed on the list, but ok it >> > is done now. Next time >> > devs should be informed before such a big commit takes place. >> > >> > cheers, >> > >> > Gerald >> > >> >> >> >> >> -- >> Arash Rajaeeyan > >