tags:

views:

450

answers:

2

Hi all! First post here...

I normally develop using PHP and Symfony with Propel and ActionScript 3 (Flex 3), using AMF services. This weekend I'm trying my hand at creating a BlazeDS application using Java and Hibernate, and I'm beginning to like Java a lot!!!

After some research this weekend and using the Hibernate Synchronizer plugin for Eclipse, creating classes mapped (excuse my terminology) to tables seem fairly easy, I'm swiftly getting closer to understanding these aspects.

What I want to know however, is how to develop a more comprehensive architecture for my database, specifically in terms of queries, their results and iterating them. Let me ellaborate:

If I have for example an authors table, I'll be creating an Author class which is mapped to the table, with getters and setters etc. This part looks pretty standard in terms of Hibernate.

Furthermore, I would probably need a Peer class (like in Propel for PHP) to for example do queries which will return a List/Array containing Author instances.

So I would have (speaking under correction) the following classes:

Author - represents a single row with getters and setters.

AuthorsPeer - has for example functions like AuthorsPeer::getAuthorsByCountry('USA'); or - AuthorsPeer::getRetiredAuthors(); or AuthorsPeer::getAuthorsWithSwineFlu(); - ... get the picture. :) - which return an AuthorsList as it's result...see next point.

AuthorsList - a collection/list of Author with functions for iterating getNext(), getPrevious() etc.

Is this the way it's meant to be in Hibernate, or am I missing the plot? Am I noticing a Design Pattern here, and not noticing it? Do I need to have something like AuthorsList, or does Hibernate provide a generic solution. All in all, what's the norm with dealing with these aspects.

Also, if I have a Books table, these are related with Authors, if I call say Author myAuthor = Authors::getAuthor(primaryId, includeBooks); can Hibernate deal with returning me a result that I can use as follows: String title = myAuthor.books[0].title;

What I'm asking is, do queries to Authors relating to Books table result in Hibernate returning Authors with their Books all nested inside the Authors "value object" ready for me to pounce with some iteration?

Thanks in advance!

A: 

Basically the answer is yes, kinda. :) If you fetch a single Author and then access the collection of Books, Hibernate will lazy load the data for you. This actually isn't the most performant way to do this but it is convenient for the programmer. Ideally you want to use something like HQL (Hibernate Query Language) or its Criteria API to execute a query and "eager fetch" the collection of books, so that all data can be loaded with a single SQL query.

http://docs.jboss.org/hibernate/stable/core/reference/en/html/queryhql.html

Otherwise if you access an Author that has say 500 Books associated to it, Hibernate may issue 500 + 1 SQL queries against the database which is of course incredibly slow. If you want to read more about this, you can Google "n + 1 selects problem" as it's commonly referred to.

cliff.meyers
A: 

The answer to most of your questions is yes. What you should really look into is how to map one-to-many relationships in Hibernate. In your case, the author is the "one" and the books are the many. Associative mappings are described there. If you are using Annotations with Hibernate (which I highly recommend over XML files), you can find out how to do associations with annotations here.

The great thing about hibernate is that you don't have to do much to manage the relationships. The following is a code snippet of what you would need for your Author-Book relationship.

@Entity public class Author {
    @OneToMany(mappedBy="author")
    public List<Book> getBooks() {
        return books;
    }
...
}

@Entity public class Book {
    public String getName() {
        return bookName;
    }

    @ManyToOne
    public Author getAuthor() {
        return author;
    }
    ...
}

To get the Authors from the table, you would use the Criteria API or HQL. I prefer the Criteria API because it goes with Java's general programming feel (unlike HQL). But your preference may differ.


On a side note: You should not create an "AuthorsList" class. Java generics does the job for you:

List<Author> myAuthors = new ArrayList<Author>();

//iterate like so
for(Author author: myAuthors) {
   //do something with current author
}

//or just grab 1
Author firstAuthor = myAuthors.get(0);

Java handles compile time checks against the types so you don't have to.

Laplie
Thanks for that! Hibernate is the shizness! :)
Joe Zephyr