Hi Ravi, sorry to not have an "easy" workaround for you but the following rules have proven to be working quite well for us when using GWT + GAEJ + JDO:
1. No Class hierarchies for JDO Objects going through GWT RPC 2. No JDO modeled 1:n relationships other List<String> (same table) 3. Implicit 1:n relationships setting parent key in child objects using queries on keys for lookup In your case this means use a field like this in your Appointment object: @Persistent @Extension(vendorName="datanucleus", key="gae.parent-pk", value="true") private String parentKey; Set this field with the employees key, then you can change both entities in the same transaction (see entity groups). Use a key lookup with a filter on the parent key field if you need a quick count on how many appointments an employee has: http://code.google.com/intl/de-DE/appengine/docs/java/datastore/queriesandindexes.html#Queries_on_Keys or a regular query with the same filter to retrieve the actual appointments. Hope this helps, Fred On 27 Aug., 23:09, hampole <[email protected]> wrote: > Thanks for the info. I looked at the issue and many other people > having problem of saving child object in a one-to-many relation. I am > new to this and I don't understand completely. Is there any work- > around to save a child object. If anyone can show me an example, I > appreciate. This is really frustrating as this is basic functionality > in any relational data. In my case, Employee object already exists and > I want to create a new appointment and associate with the employee > object. If there is a different way of doing this, please help. This > has taken quite a lot of time and if this is not available in GWT, I > don't think I can use Google apps for the development of our > application. I appreciate any help. > > Thanks, > Ravi > > On Aug 27, 1:51 am, Frederik Pfisterer <[email protected]> wrote: > > > Your problem seems to be related to this open gwt > > issue:http://code.google.com/p/google-web-toolkit/issues/detail?id=4976 > > > Please star the issue to raise its attention. The workaround is not > > using 1:n relationships with GWT + GAE + JDO. > > > Cheers, > > Fred > > > On 26 Aug., 23:12, hampole <[email protected]> wrote: > > > > I am trying to develop GAE application. I am using the latest GWT > > > SDK(2.0.4) AND App Engine SDK(1.3.6) on Eclipse3.4. I am having > > > problem insavinga childobject"Appointment" and the parentobject > > > is "Employee". Each Employee has many appointments and and each > > > appointment has one employee associated with. I have pasted the Client > > > code and the server code here. Please help and see what I am missing > > > here. I tried many different ways without success. When I retrieve the > > > appointments, the employee is always null. I appreciate any help or > > > some example that I can try. Thanks. > > > > //Client code > > > public class AppointmentCreateWidget extends Composite { > > > > private static AppointmentCreateWidgetUiBinder uiBinder = GWT > > > .create(AppointmentCreateWidgetUiBinder.class); > > > > interface AppointmentCreateWidgetUiBinder extends > > > UiBinder<Widget, AppointmentCreateWidget> { > > > } > > > > @UiField Button btnSaveAppointment; > > > @UiField TextBox tbxSubject; > > > @UiField ListBox lbxRoom; > > > @UiField ListBox lbxHost; > > > @UiField DateBox dbAppointStartDate; > > > @UiField DateBox dbAppointEndDate; > > > @UiField ListBox lbxStartTimeHr; > > > @UiField ListBox lbxEndTimeHr; > > > @UiField ListBox lbxStartTimeMi; > > > @UiField ListBox lbxEndTimeMi; > > > > private final AppointmentServiceAsync appointService = > > > (AppointmentServiceAsync) GWT.create(AppointmentService.class); > > > private final List<Visitor> visitors = new ArrayList<Visitor>(); > > > > public AppointmentCreateWidget() { > > > initWidget(uiBinder.createAndBindUi(this)) > > > } > > > > @UiHandler("btnSaveAppointment") > > > void onClick(ClickEvent e) { > > > addAppointment(); > > > } > > > > private void addAppointment() { > > > String subject = tbxSubject.getText().toUpperCase().trim(); > > > Date startdate = dbAppointStartDate.getValue(); > > > Date enddate = dbAppointEndDate.getValue(); > > > String starttime = > > > lbxStartTimeHr.getValue(lbxStartTimeHr.getSelectedIndex()).toString() > > > + > > > > > > lbxStartTimeMi.getValue(lbxStartTimeMi.getSelectedIndex()); > > > String endtime = > > > lbxEndTimeHr.getValue(lbxEndTimeHr.getSelectedIndex()).toString() + > > > lbxEndTimeMi.getValue(lbxEndTimeMi.getSelectedIndex()); > > > String room = > > > lbxRoom.getValue(lbxRoom.getSelectedIndex()).toString(); > > > String key = lbxHost.getValue(lbxHost.getSelectedIndex()); > > > DateTimeFormat dateFormat = > > > DateTimeFormat.getShortDateFormat(); > > > > try { > > > createAppointment(subject, startdate, enddate, > > > starttime, > > > endtime, key, visitors); > > > } > > > catch(Exception ex) { > > > Window.alert("Save Appointment failed: " + ex.toString()); > > > } > > > } > > > > private void createAppointment(String subject, Date startdate, > > > Date > > > enddate, String starttime, String endtime, String empID, List<Visitor> > > > visitor) { > > > appointService.addAppointment(subject,startdate, enddate, > > > starttime, endtime, empID, visitor, new AsyncCallback<Void>() { > > > public void onFailure(Throwable error) { > > > Window.alert("Unable to create Appointment." + > > > error.getMessage()); > > > } > > > public void onSuccess(Void ignore) { > > > } > > > }); > > > } > > > > } > > > > //ServiceImpl > > > public class AppointmentServiceImpl extends RemoteServiceServlet > > > implements AppointmentService { > > > /** > > > * > > > */ > > > private static final long serialVersionUID = 1L; > > > > public void addAppointment(String subject, Date appointStartDate, > > > Date appointEndDate, String startTime, String endTime, String empID, > > > List<Visitor> visitors) throws NotLoggedInException { > > > PersistenceManager pm = getPersistenceManager(); > > > //get employee > > > Employee emp = pm.getObjectById(Employee.class, empID); > > > > Appointment newAppoint = new Appointment(subject, > > > appointStartDate, appointEndDate, startTime, endTime); > > > newAppoint.setVisitors(visitors); > > > newAppoint.setEmployee(emp); > > > emp.getAppointments().add(newAppoint); > > > > try { > > > pm.makePersistent(emp); > > > } finally { > > > pm.close(); > > > } > > > } > > > > private PersistenceManager getPersistenceManager() { > > > return PMF.get().getPersistenceManager(); > > > } > > > > } > > > > //Employee Bean > > > @PersistenceCapable(identityType = IdentityType.APPLICATION, > > > detachable = "true") > > > public class Employee implements IsSerializable, IValidatable { > > > > @PrimaryKey > > > @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) > > > @Extension(vendorName="datanucleus", key="gae.encoded-pk", > > > value="true") > > > private String employeeKey; > > > > @NotEmpty(message="You must specify First Name") > > > @Length(minimum=3) > > > @Persistent > > > private String firstName; > > > > @NotEmpty(message="You must specify Last Name") > > > @Length(minimum=3) > > > @Persistent > > > private String lastName; > > > > @Persistent > > > private String title; > > > > @NotEmpty(message="You must specify Email Address") > > > @Length(minimum=3) > > > @Persistent > > > private String email; > > > > @Persistent > > > private String department; > > > > @Persistent > > > private String phone; > > > > @Persistent > > > private String extension; > > > > @Persistent > > > private String companyName; > > > > @Persistent(mappedBy = "employee") > > > @Element(dependent = "true") > > > private List<Appointment> appointments; > > > > public Employee(String firstName, String lastName, String title, > > > String email, > > > String phone, String extension, String department, > > > String > > > companyName) { > > > this(); > > > this.firstName = firstName; > > > this.lastName = lastName; > > > this.title = title; > > > this.email = email; > > > this.department = department; > > > this.phone = phone; > > > this.extension = extension; > > > this.companyName = companyName; > > > } > > > > //getters and setters > > > > } > > > > //Appointment Bean > > > @PersistenceCapable(identityType = IdentityType.APPLICATION, > > > detachable = "true") > > > public class Appointment implements IsSerializable, IValidatable { > > > > @PrimaryKey > > > @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) > > > @Extension(vendorName="datanucleus", key="gae.encoded-pk", > > > value="true") > > > private String appointKey; > > > > @Persistent > > > private String subject; > > > > @NotEmpty(message="You must specify Start Time") > > > @Persistent > > > private String startTime; > > > > @NotEmpty(message="You must specify End Time") > > > @Persistent > > > private String endTime; > > > > @NotEmpty(message="You must specify Start Date") > > > @Persistent > > > private Date appointmentStartDate; > > > > @NotEmpty(message="You must specify End Date") > > > @Persistent > > > private Date appointmentEndDate; > > > > @Persistent > > > private Employee employee; > > > > @Persistent > > > private List<Visitor> visitors = new ArrayList<Visitor>(); > > > > public Appointment(String subject, Date appointStartDate, Date > > > appointEndDate, String startTime, String endTime, Employee employee, > > > List<Visitor> visitors) > > > { > > > this(); > > > this.subject = subject; > > > this.startTime = startTime; > > > this.endTime = endTime; > > > this.appointmentStartDate = appointStartDate; > > > this.appointmentEndDate = appointEndDate; > > > > > ... > > Erfahren Sie mehr » -- You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en.
