I have a fairly large (new) project in which we have annotated many domain classes with JPA mappings. Now it is time to implement many named queries -- some entities may have as many as 15-20 named queries. I am thinking that writing these named queries in annotations will clutter the source files and therefore am considering putting these in XML mapping files.
Is this possible?
Mort importantly, is this reasonable?
Are there better approaches?
How is this done?
Is this possible?
Yes it is, but the trend is more to centralize things, not the inverse.
More importantly, is this reasonable?
I am not annoyed by a having a block of annotations at the top of my entities class files. Actually, I like to have my queries where I think they belong: next to entities. I also like the compile time checks (on entity names, attributes) and the code completion I get when writing queries in the Java code (not sure my IDE would do that with xml mappings). In other words, I don't feel the need and don't want to externalize queries .
Are there better approaches?
I believe that using annotations is the best practice1.
How is this done?
The recommendation is to use XML mapping files only for native SQL statements that are specific to a particular database (of course, I omit the obvious case of legacy code that you can't annotate). In other words, use annotations but keep the code as free from vendor-specific stuff as possible.
1 The JPA 1.0 specification co-lead Mike Keith covered many of the trade-offs associated with an XML metadata strategy (XML strategy) versus an in-source metadata strategy (annotations strategy) in the OTN column "To Annotate or Not". Sadly, I couldn't find a non-dead link to his publication. Maybe you'll be more lucky and in that case, read it.
I know this is a little late but I came across this and in my project I have been using org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean (in the Spring container, of course). I really like JPA and I am sure it will make life easier but I want to use my domain classes in a project that does not use Hibernate, JPA, Spring or any of that good stuff. We decided that it would be better to leave some of our domain classes free of Java Persistence annotations if possible.
I know this is a simple thing that is probably obvious to many but it took me a while. Below is my example POJO note that I have no annotations:
package mypackage.domain;
public class Profile {
private Long id;
private String friendlyName;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getFriendlyName() { return friendlyName; }
public void setFriendlyName(String friendlyName)
{ this.friendlyName = friendlyName; }
}
In the src/main/java/mypackage/domain/
directory (if you are using Maven) you should put a nice, traditional XML mapping file (Profile.hbm.xml):
<hibernate-mapping package="mypackage.domain" default-access="field">
<class name="Profile" table="Profile">
<id name="id" column="ID">
<generator class="native" />
</id>
<property name="friendlyName" column="FriendlyName" />
</class>
</hibernate-mapping>
Provided you are using Hibernate 4.0.0.CR3 that should be ok, The Spring configuration (I am using 3.0.6.RELEASE) can then look like a typical JPA Hibernate configuration:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="SQL_SERVER" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>
META-INF/persistence.xml
is pretty basic and, for completeness here it is:
<persistence version="1.0">
<persistence-unit name="default" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>mypackage.domain.Profile</class>
</persistence-unit>
</persistence>
Of course, although I am using JPA the mapping configuration is Hibernate specific and so I have tied myself to Hibernate in this project, since I am using pure JDBC in the legacy sister project I do not see it as such a drawback.
It's possible, but I don't think it's needed. I work on a lot of big projects with many named queries attached to some entities and I don't think that this clutters the source much - after all the queries are all before the class definition. The main advantage of using annotations is that you can see everything in the source. If you've extracted the queries in an xml config the presence of the named queries won't be immediately visible which I'd consider a drawback. I like to keep stuff pure - either xml only setup or only annotations setup. The only xml config I generally keep around on JPA projects in the persistence.xml.