This code saves the child for me, however, the parent property of the child (in your case "book") is null in the child. I have tried deliberately setting this child "parent" property myself to the parent prior to commit, but nothing seems to work.
On Sep 28, 6:45 pm, Max Ross <[email protected]> wrote: > Hello again and welcome to Episode 3 of JDO/JPA Snippets That Work. Today's > episode is called...... > > Updating A Bidrectional Owned One-To-Many With A New Child > > All the way back in episode one we demonstrated how to create both a parent > and a child of a bidirectional, owned, one-to-many relationship > at the same time. This week we're going to see how to add a child to an > existing parent. We'll use the same model objects we used in episode one: > > JPA: > @Entity > public class Book { > @Id > @GeneratedValue(strategy=GenerationType.IDENTITY) > private Key id; > > private String title; > > @OneToMany(mappedBy = "book", cascade = CascadeType.ALL) > private List<Chapter> chapters = new ArrayList<Chapter>(); > > // getters and setters > > } > > @Entity > public class Chapter { > @Id > @GeneratedValue(strategy=GenerationType.IDENTITY) > private Key id; > > private String title; > private int numPages; > > @ManyToOne(fetch = FetchType.LAZY) > private Book book; > > // getters and setters > > } > > Now let's assume we've already created a book with a few chapters in the > datastore and we want to add a brand new chapter to a Book with a given id > (we'll assume someone else is creating and closing an EntityManager named > 'em' for us): > > public void addChapterToBook(EntityManager em, Key bookKey, Chapter chapter) > { > em.getTransaction().begin(); > try { > Book b = em.find(Book.class, bookKey); > if (b == null) { > throw new RuntimeException("Book " + bookKey + " not found!"); > } > b.getChapters().add(chapter); > em.getTransaction().commit(); > } finally { > if (em.getTransaction().isActive()) { > em.getTransaction().rollback(); > } > } > > } > > JDO: > > @PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = > "true") > public class Book { > > @PrimaryKey > @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) > private Key id; > > private String title; > > @Persistent(mappedBy = "book") > @Element(dependent = "true") > @Order(extensions = @Extension(vendorName="datanucleus", key= > "list-ordering", value="id asc")) > private List<Chapter> chapters = new ArrayList<Chapter>(); > > // getters and setters > > } > > @PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = > "true") > public class Chapter { > @PrimaryKey > @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) > private Key id; > > private String title; > private int numPages; > > @Persistent > private Book book; > > // getters and setters > > } > > Now let's assume we've already created a book with a few chapters in the > datastore and we want to add a brand new chapter to a Book with a given id > (we'll assume someone else is creating and closing a PersistenceManager > named 'pm' for us): > > public void addChapterToBook(PersistenceManager pm, Key bookKey, Chapter > chapter) { > pm.currentTransaction().begin(); > try { > // throws a runtime exception if book is not found > Book b = pm.getObjectById(Book.class, bookKey); > b.getChapters().add(chapter); > pm.currentTransaction().commit(); > } finally { > if (pm.currentTransaction().isActive()) { > pm.currentTransaction().rollback(); > } > }} > > -------------------------------- > > The interesting thing about both of these examples is that we're not making > any explicit calls to save the new Chapter. We look up the Book identified > by the Key that was passed into the function and then we manipulate the > persistent state of the object by manipulating the POJO that was returned by > em.fetch/pm.getObjectById. JPA and JDO both have mechanisms that allow them > to monitor the objects that you've looked up for changes. Ever wonder what > exactly the enhancer is doing to your classes? It's adding hooks so that > the persistence framework gets notified when things change (among other > things). This allows JPA and JDO to automatically flush your changes to the > datastore when you commit your transaction. If you wanted to modify the > title of the Book or the number of pages in an existing Chapter the approach > would be exactly the same: Start a transaction, look up the Book, make your > changes, commit your transaction. Whether you're using JPA or JDO your > changes will be persisted for you without any explicit calls to change the > persistent state. This is a prime example of how JPA and JDO facilitate > "transparent persistence." --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
