Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

  • sjivan
    replied
    Originally posted by alius
    Hi,

    Problem is that response.setData () accepts only ListGridRecord[].

    (Question to Sanjiv: if DSResponse is quite general object, DataSource objects are used not only in ListGrid - why it accepts only one type of record? Possible solutions would be:
    1. accept Record[];
    2. add setData methods with different parameters.
    )


    You can try to overcome this (I haven't tried it myself):

    Create TileRecord[] (fill it with data from List you've got from server).
    Instead of response.setData (list) use response.setAttribute ("data", list);

    Hope that helps,
    Aleksandras
    DSResponse.setData now accepts Record[].

    Sanjiv

    Leave a comment:


  • jasonzhang2002
    replied
    Is there a good way to integrate the RPCRequest.showPrompt(...) to GWT-RPC DataSource? In current implementation, the cursor pointer is always pointer cursor. There is no indication to end user the browser is busy in communicating with server.
    thanks
    -jason

    Leave a comment:


  • Mr Vincent
    replied
    Hello,

    I use your DataSource implementation and I have a little problem in my executeUpdate method. My grid is always sorted and when I update a record, this record is add in the end of the grid (the grid becomes unsorted).

    Are there any solution to resolve my problem?

    thx

    Leave a comment:


  • skoder
    replied
    Hello.
    In example DS (TestDataSource.java) @alius creates new record in ExecuteAdd method, for example:

    Code:
    TestRecord testRec = new TestRecord ();
    Is there any way to use existence domain object instead of creating new. For example: I have a form, which contain data from fetched domain object and I want save this object. I should transmit object to DS, where I can copy values from ListGrid to object attributes and then merge it using Gilead.

    Thanks. Any help would be appreciated.

    Leave a comment:


  • kinglear
    replied
    clientContext

    I there some documentation on the (for me) strange:

    Object clientContext = dsRequest.getAttributeAsObject("clientContext")

    and later:

    dsResponse.setAttribute("clientContext", clientContext);

    why is this needed? if I remove it in my DS implementation, the DS stops working.

    Leave a comment:


  • bodrin
    replied
    Originally posted by mivola
    Hi bodrin,

    Thanks for your help!

    Yes, i'm using the domain objects directly using hibernate4gwt/gilead (thats what it is designed for). And I'd like to keep it this way because I just dont like the idea of having additional DTO's.
    Therefore I'd like to explore the second alternative you described. Could you describe that in a more detailed way, possibly with a small example?

    Thanks in advance!
    Michael
    Ok, in your case may be it is better to do it with Gilead .. I haven't tried this.

    For the other option - you might cluster your entites into aggregates (http://domaindrivendesign.org/freelinking/Aggregate)
    and do read/create/update on aggregate level.
    Here is a rough example. We have User, Profile and Phone. User has many Profile-s.
    Each Profile has a Phone. Lets say the aggregates are (User) and (Profile + Phone) with the aggregate
    roots User and Profile correspondingly.

    Code:
    @Entity
    public class User {
    	@Id
    	private int id;
    	
    	private String firstName;	
    	private String lastName;
    		
    	@OneToMany( mappedBy = "owner" )
    	protected Set<Profile> profiles = new HashSet<Profile>();
    	
    	// ...
    }
    
    @Entity
    public class Profile {
    	@Id
    	private int id;
    	
    	@ManyToOne( optional = false, fetch = LAZY )
    	private User owner;
    	
    	@OneToOne( optional = false )
    	Phone phone;
    	
    	private Status status;
    	// ...
    }
    
    @Entity
    public class Phone {
    	@Id
    	private int id;
    	
    	private String number;
    	// ...
    }
    
    public class RemoteFacadeImpl {
    
    	public void updateProfile(Profile newProfile) {
     
    		Profile oldProfile = em.find(Profile.class, newProfile.getId());
    		
    		// fix some relations
    		newProfile.setUser(oldProfile.getUser());
    		
    		// do udpate - affects only Profile and Phone related objects
    		newProfile = em.merge(newProfile);
    	}
    	
    	// public void createProfile(Profile newProfile) {}
    	// deleteProfile(int profileId){}
    	
    	// public void createUser(User newUser) {}
    	// public void updateUser(User newUser) {}
    	// public void deleteUser(int userId) {}
            // + methods to manage the User - Profile relation
    }
    If you are interested in this approach it might be better to find some other resources (like DDD), because in this talk we should discuss more SmartGWT related things.

    Hope this helps.

    Leave a comment:


  • grady80
    replied
    Looks like I can accomplish this with a poll() and add the records using:

    DataSource.updateData(Record record)
    DataSource.addData(Record record)
    DataSource.removeData(Record record)

    So, my ( hopefully ) last part of the puzzle is, how can I prevent data ringing for records added programmatically like this. If I call DataSource.addData, that triggers GwtRpcDataSource.executeAdd() sending the record back to the server ( which it just came from )

    I found that in my Datasource implementation I can key off of request.getComponentId() to see if this came from the result of a UI modification or a programmatic modification.

    Example executeAdd:

    ...
    if (null != request.getComponentId()){
    //This came from the UI make the RPC call and process Response
    }
    else{
    processResponse(requestId, response);
    }

    Leave a comment:


  • grady80
    replied
    Thanks for the response.

    I am trying to update a widget based on a poll() where I am not getting an entire "set" back, but rather just those that have been Created, Updated, or Deleted server side after an initial fetch().

    So, does this make sense?

    1) Extend GwtRpcDataSource.java to add an abstract method "public void poll()"
    2) In my GwtRPCDataSource implementation, implement the poll() method and have it make a GWT-RPC call to RPCPoll().
    3) Set up a timer in the class holding the Widget to go off every X seconds. The poll() method is then called on the datasource.

    My question is, how do I update the datasource with the results of the RPCPoll(). ( assume that I know the CRUD verb and the records Primary Key )

    My guess is I will have to make a call to DataSource.getData() and manually mangle the data to create/update/delete the polled records.

    Once I do this, and do a DataSource.setData() with this manually mangled list, will the widget be notified of the changes?

    Thanks

    Leave a comment:


  • alius
    replied
    Hi,

    DataSource itself is passive.

    Widget is initiating call.

    Aleksandras

    Leave a comment:


  • grady80
    replied
    GWT-RPC Polling

    Hello,

    Thank you for the datasource. Works great.

    Does anyone have any thoughts as far as the extending this datasource to accomplish regular polling ( say every 5 sec ) ?

    Should the timer trigger happen within the datasource? i.e. every 5 seconds a GWT-RPC poll() call is made and the setData method called with the response.

    Or should it happen at the widget level with a call to invalidate cache ( which would trigger a new fetch() ? )

    Thanks

    Leave a comment:


  • alius
    replied
    Hi Michael,

    With RPC you are updating only entity itself.
    You can use @ReadOnly annotation from Gilead on collection property.

    Aleksandras

    Originally posted by mivola
    Hi bodrin,

    Thanks for your help!

    Yes, i'm using the domain objects directly using hibernate4gwt/gilead (thats what it is designed for). And I'd like to keep it this way because I just dont like the idea of having additional DTO's.
    Therefore I'd like to explore the second alternative you described. Could you describe that in a more detailed way, possibly with a small example?

    Thanks in advance!
    Michael

    Leave a comment:


  • smartgwt.dev
    replied
    Just a fyi that SmartGWT EE solves this problem most elegantly even compared to a gilead based solution.

    Here's why :
    - Only properties declared in the datasource are extracted from the (Hibernate managed) domain model without the use of any DTO's. Moreover the user does not have to worry about excessive subsets of the object graph being sent over to the client. With a gilead based solution, the user is still responsible of managing which subset of the domain model is sent to the client on a per-screen basis. Some screens might be displaying associations which are lazy loaded by Hibernate while others might only display information from top level bean properties.

    - Updates are managed transparently with SmartGWT EE, even if the modified property is nested, or part of a lazy association.

    For a better understanding check out the Hibernate based samples in SmartGWT EE.
    Last edited by smartgwt.dev; 15 Apr 2009, 08:41.

    Leave a comment:


  • mivola
    replied
    Originally posted by bodrin
    2) Keep using the domain model, but fix all the relations into the RemoteFacade (on write). The RemoteFacade contract is for example:
    -readX(...) - returns domain object instance of X with prefetched relations x.a,x.b,x.c,x.a.m,x.a.m.p, x.a.m.p.q,...
    (you specify the exact island of the object graph returned by each read method, so that the client knows how deep it can explore each relation)
    -writeX(x) - expected domain object instance of X with related objects x.a, x.b,x.a.m and x.a.m.p (so here the RemoteFacade will first select all the relations of x object which you want to preserve, then merge the new changes and finally restore all relations broken by the merge)
    Hi bodrin,

    Thanks for your help!

    Yes, i'm using the domain objects directly using hibernate4gwt/gilead (thats what it is designed for). And I'd like to keep it this way because I just dont like the idea of having additional DTO's.
    Therefore I'd like to explore the second alternative you described. Could you describe that in a more detailed way, possibly with a small example?

    Thanks in advance!
    Michael

    Leave a comment:


  • bodrin
    replied
    Originally posted by mivola
    Hi all,

    thanks a lot for this really helpful pattern! I got it working for my project in almost no time!

    But now I came across a problem. My domain objects have different relations to each other (OneToMany, ManyToMany) that are implemented as javax.persistence annotations. E.g. one User has a list of Roles (@ManyToMany(mappedBy="users")).

    When I now create a UserDataSource based on the GwtRpcDataSource, I can load the records and change the primitive members (first name, last name, ...). The changes are also saved properly, but also the list of roles is set to null and therefore deleted.

    My question is: how can I display (and modify) the roles? If that is not possible, how can I at least preserve the existing associations?

    If this problem cannot bo solved this pattern is IMHO quite useless for real-world domains.

    Thanks for your help!!
    Michael
    Hi mivola,

    I think the problem is that you are trying to use domain objects at the client side. You can not load the whole object graph at the client, because the JPA merge destroys your relations for example (server side implementation details should not leak into the client).

    I have had the same problems and found some ways to solve them:

    1) Use RemoteFacade with DTO object model instead using directly the domain model. This has been discussed a lot. The main advatage is that you can change your domain model without changing the client code. The main disadvantage is that you have to map between domain model and DTOs and if you are doing it manually it is a nightmare, so better use some framework (I like dozer).

    OR

    2) Keep using the domain model, but fix all the relations into the RemoteFacade (on write). The RemoteFacade contract is for example:
    -readX(...) - returns domain object instance of X with prefetched relations x.a,x.b,x.c,x.a.m,x.a.m.p, x.a.m.p.q,...
    (you specify the exact island of the object graph returned by each read method, so that the client knows how deep it can explore each relation)
    -writeX(x) - expected domain object instance of X with related objects x.a, x.b,x.a.m and x.a.m.p (so here the RemoteFacade will first select all the relations of x object which you want to preserve, then merge the new changes and finally restore all relations broken by the merge)

    OR

    3) CQS - this is similar to DTOs approach, but the writes are done through commands/messages (which again are DTOs), so that you will not use JPA merge, but instead: select object(s), then throw command(s) into them (the effect of which can be create/update/delete) and finally commit.

    Hope this helps.

    Leave a comment:


  • farmer
    replied
    Well the DataSource only holds the field you defined, not the complete ValueObjects.
    So maybe you just need to store your list somewhere (inside your custom DS?) and for updating take the original object and replace the values from the DS.
    That way, you don't loose "hidden" data you do not manage with the DS.

    Leave a comment:

Working...
X