views:

127

answers:

3

Suppose I have a Java or C# application in which I have classes like Book, Library, Author, ... and I want an easy way to map these items to database, or show them in a data grid.

I could implement interfaces for all these classes specifically for the data grid and for the database interaction, but this may mean quite some work whenever:

  • a new class is added (e.g. Loaner, Publisher, ...)
  • a new generic module is added (e.g. a reporting module in which the user may choose which information of the class to show in the report)

An alternative is to rely on the reflection capabilities of Java and C# and simply use this information to build the data grid and the database interface. Is this a logical approach or is it better not to rely on reflection and write explicit interfaces for every class-module combination (book-datagrid, book-database, book-report, library-datagrid, library-database, library-report, author-datagrid, ...)?

For the database-mapping, tools like Hibernate could be used, but does Hibernate also rely on reflection or do you have to implement an explicit interface for each of your classes as well to make use of Hibernate?

+1  A: 

Yes, NHibernate makes heavy use of reflection. For rendering grids, have a look at the data templates in WPF since you will be able to control the rendering of different cells based on the Type of data you are showing in the column.

Douglas
+1  A: 

Here is a nice article addressing some of the issues. Hibernate does use runtime reflection, but at times you will have to tune things a bit. Full automation of the persistence problem is not there yet. One of the great advantages of reflection is lower chance of human error.

whatnick
+1  A: 

If you are mapping data to a database, you probably want to investigate the Java Persistence Architecture (JPA) standard. Classes are annotated with tags which define table fields, relationships etc. without materially affecting how code which is not interested in that stuff interacts with the class. It's a POJO in other words.

JPA implementations such as Hibernate & OpenJPA use the annotations to load / store the entity from a datasource which would usually be a SQL database but strictly speaking doesn't have to be.

A class which is stored in a database is annotated as an @Entity and contains fields which may be persistent or transient. You can also specify the @Column a field maps to into the database and use @OneToOne, @ManyToOne and @OneToMany annotations with @JoinTable, @JoinColumn to define relationships between entitles.

Entities are stored / retrieved via an EntityManager and query language.

e.g.

@Entity
@Table(name = "BOOKS")
class Book {
  @Id
  @Column(name = "BOOK_ID")
  int bookId;

  @ManyToOne
  @JoinColumn(name = "AUTHOR_ID", insertable = false, updatable = false)
  Author author;

  @Column(name = "TITLE")
  String title;

  @Transient
  double relevanceScore;
}

@Entity
@Table(name = "AUTHORS")
class Author {
  @Id
  @Column(name = "AUTHOR_ID")
  int id;

  @Column(name = "NAME")
  String name;

  @OneToMany(mappedBy = "AUTHORS")
  @JoinColumn(name = "AUTHOR_ID")
  Set<Book> books;
}

And to utilise it:

Query q = getEntityManager.createQuery("SELECT b FROM Book b WHERE b.title = :title");
q.setParameter("title", title);
return q.getResultList();

In the case of Hibernate you have a choice whether to use JPA style annotations or external XML mapping files. Annotations are probably easier to maintain in most cases, but XML might be useful if you want to play around with mappings at runtime without rebuilding the source code. The latter might be useful if you have a single entity and depending on deployment it's stored against different data sources.

locka