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
>
>