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."
转载自:
http://groups.google.com/group/google-appengine-java/browse_thread/thread/28d9c3b99df25e43#
分享到:
相关推荐
WinCEPB60-081231-Product-Update-Rollup-Armv4I补丁包,分卷压缩的,下载6个压缩包后解压缩即可。
myeclipse-10.6-archived-update-site.part07
springsource-tool-suite-2.9.2.RELEASE-e3.6-updatesite.part3
F5部署红宝书3部 F5部署红宝书pdf资源,Part I - 基础安装部署,Part II --互联网出口部署,Part III - 服务器前端部署 F5部署红宝书pdf资源,Part I - 基础安装部署,Part II --互联网出口部署,Part III - 服务器...
WinCEPB60-081231-Product-Update-Rollup-Armv4I补丁包,分卷压缩的,下载6个压缩包后解压缩即可。
myeclipse-10.0-archived-update-site.part01
CSDN限制最多上传70M的单文件,所以压了三个包,不用痛苦去下6个包了
WinCEPB60-081231-Product-Update-Rollup-Armv4I.msi补丁包,分卷压缩的,下载6个压缩包后解压缩即可。上传失败了,请勿下载。
myeclipse-10.6-archived-update-site.part14
GWT Plugin For Eclipse(2)第二部分 Google Web Toolkit gpe-e36-latest-updatesite.part2.rar 最新插件
gpe-e37-latest-updatesite.part3
2. **OPC-UA Part 3 - 地址空间模型**:这部分定义了如何在OPC UA服务器中组织和表示数据,如节点、对象、变量、方法等,构成了OPC UA的核心数据结构。 3. **OPC-UA Part 4 - 服务**:这部分详述了OPC UA提供的各种...
myeclipse-10.6-archived-update-site.part03
myeclipse-10.6-archived-update-site.part10
myeclipse-10.6-archived-update-site.part12
myeclipse-10.6-archived-update-site.part11
myeclipse-10.6-archived-update-site.part13
myeclipse-10.6-archived-update-site.part01
myeclipse-10.6-archived-update-site.part02
myeclipse-10.6-archived-update-site.part06