Showing posts with label Hibernate. Show all posts
Showing posts with label Hibernate. Show all posts

Wednesday, June 11, 2008

What I Like to See in JPA 2.0

What I like to see in JPA 2.0 final specification.

1. Support for setting collection parameters in JPQL: Collections<object> in a Query in places where a list of objects is acceptable. For example a very common issue is for 'IN' keyword in JPQL:

SELECT mo FROM MyObject mo WHERE mo.id IN (:idList)


Here users should be allowed to set a collection with underling elements of type MyObject.id.

2. Basic support for object comparison (equals) in JPQL:

manager.createQuery("SELECT b FROM Book b WHERE b.author = :p").setParameter("p", managedAuthorObject);

3. When writing an application-level generic search, it's almost impossible to use a NamedQuery. Many JPA 1.0 implementers (Hibernate and EclipseLink for example) support Query-by-example which makes life really much easier when writing search queries.

Since it's very likely that users (application-level) do not enter search criteria values (null values for criteria object), it's useful to let search work without setting some parameters (or setting them to a constant field meaning IGNORE). In this case a default action (which can be customized) can be taken. For example this case:

Query q = manager.createQuery("SELECT p FROM Person p WHERE p.name = :name AND p.age = :age");
if (name is available)
q.setParameter("name", name);
if (age is available)
q.setParameter("age", age);
q.findAll();


It would be really great if 2.0 spec force implementers to support a Query by example, something like this:

Person person = new Person("Bob", 28);
manager.findByExample(person);


A similar mechanism is currently supported by both Hibernate (Criteria query) and TopLink/EclipseLink.

4. LIKE operator for non-String fields. Some database engines support this, and it's good IMHO to recommend implementers to just ignore LIKE (in favor of == operation) if underlying DBMS doesn't support it.

5. Support for @GeneratedValue which is not also @Id. There are many cases that developers need to generate another unique value other that the original entity PK. Since now spec has SEQUENCE and IDENTITY, which are not portable to all DBMSes, @GeneratedValue may also be limited in some DBMSes.

6. Support for interceptors: events that are raised just before or after some special actions: @AfterCommit, @BeforeDelete, .... These annotations may be set globally on the BaseEntity class which is a @MappedSuperClass of other entities, in order to be applied on all entities. It's very useful for injecting different cross-cutting concerns.

7. More consistent persistence.xml schema among different implementations. Almost all configurations (from Database URL, to Logging level) are set as generic key-value pairs in persistence.xml. So in the simplest project you should have two different versions of persistence.xml, for instance one for EclipseLink and one for Hibernate. Many of these settings (specially database connection info) can be set through a general schema.

8. User may want to set another *.xml other than the one on META-INF/persistence.xml for configurations. It's very useful that PersistenceFactory allows a file name, URL, or InputStream to set as persistence.xml content.

A similar mechanism is currently supported by both Hibernate and TopLink.

Friday, November 16, 2007

How to use TopLink along with JBoss

JBoss is bundled with Hibernate as the default JPA/EJB3 persistence implementation, like GlassFish which is bundled with TopLink essentials. Developers who are trying to use TopLink in an application which is to be deployed on JBoss may face with some difficulties.

Persistence implementation class is referenced in persistence.xml. Since Hibernate JPA implementation is referenced somewhere in persistence.xml in a META-INF folder visible in JBoss classpath, javax.persistence.Persistence finds at least two implementations: TopLink (which is deployed with the application, and you put persistence.xml in your classes/META-INF) and Hibernate. A call to EntityManagerFactory implementation constructor is done through reflection. If it returns null, Persistence tries with the next implementation found. The problem here is that a call to Hibernate's EntityManagerFactory cannot be done, since Hibernate classes (org.hibernate.*) are not visible in the current classloader's classpath, so your application fails to deploy with a ClassCastException for Hibernate's EntityManagerFactory implementation. To overcome this problem you need to do a small trick. Just copy hibernate-entitymanager.jar inside WEB-INF/lib folder, so that org.hibernate.ejb.HibernateEntityManagerFactory is visible in class path. Since all hibernate libraries are not available and also you specified another implementation (TopLink) in your META-INF/persistence.xml, Hibernate is bypassed and TopLink is used instead.