|
A couple of recent discussions reminded me that inserting / updating
cascaded objects, e.g. for collections, is a bit difficult to do and a bit hard to get my head around. What I'm trying to understand is the best practice for this sort of thing, or perhaps a way of using Mybatis (or an enhancement to it) that I haven't thought of. A simple example from a previous topic to illustrate what I mean: An Author has a collection of Blogs. Each Blog has only one Author but an Author has many Blogs. public class Author { private long id; private String name; private List<Blog> blogs; } public class Blog { private long id; private long authorId; private String subject; private String content; } So we have a method on Author to add a new Blog: public void addBlog(Blog blog) { blogs.add(blog); blog.setAuthorId(this.getId()); // need to persist change on blog now } Persisting the change in the blog state is the problem that I am scratching my head over. One solution is to call a DAO or mapper in the addBlog() method above to update the blog object, but this breaks the abstraction between model and persistence, because we have these DAO calls scattered throughout the Author class. Another solution is to implement a cascade at the DAO level, so we would have an AuthorDAO.update() method that would look something like: public void update(Author author) { //sql mapper update for author for (Blog blog : author.getBlogs()) { getBlogDao().update(blog); } } This second solution has a few issues as well. First, it's calling a lot of unnecessary updates on the blog objects, which multiply if those blogs themselves have collections. Second, we made the change to the blog object, but we are calling update on the parent author even though it didn't actually change. The third solution that I can think of is to simply call update on the blog object by the client code, eg: author.addBlog(myBlog); blogDao.update(myBlog); Which seems straightforward, but doesn't work well with side-effects to the rest of the collection. E.g. if I have a PhotoSet which contains Photos and I move a photo up in the order we have: public class Photo { private int id; private int photoSetId; private int sortOrder; } public class PhotoSet { private int id; private List<Photo> photos; public void movePhotoUp(Photo photo) { swapOrder(photo, getPredecessor(photo)); // swapOrder changes the sortOrder field on each photo, ie. swaps their values // so that a re-sort makes their order swap } } so any client code which went: photoSet.movePhotoUp(myPhoto); photoDao.update(myPhoto); would correctly update myPhoto's sortOrder field but not myPhoto's predecessor. So after that long-winded discussion what I'm asking is what is the best way to manage a collection within it's parent container? Raj. |
| Powered by Nabble | Edit this page |
