Key / Id Property ermitteln#

Session session = (Session)entityManager.getDelegate();
ClassMetadata metadata = session.getSessionFactory().getClassMetadata(type);
String keyName = metadata.getIdentifierPropertyName();
Class<?> keyType = metadata.getIdentifierType().getReturnedClass();

Spring JPA#

applicationContext.xml:
	<context:component-scan base-package="com.intersult"/>
	<aop:config proxy-target-class="true"/>
	<aop:aspectj-autoproxy/>
	
	<bean id="dataSource" class="${dataSource.class}" destroy-method="close">
		<property name="URL" value="${dataSource.url}"/>
		<property name="user" value="${dataSource.username}"/>
		<property name="password" value="${dataSource.password}"/>
	</bean>
	
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<property name="loadTimeWeaver">
			<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
		</property>
	</bean>

	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory"/>
	</bean>

	<tx:annotation-driven/>

Lazy-Loading und Transaction Management#

Es ist praktikabel, das JPA Transaction Management zusammen mit Spring zu verwenden (Annotation <tx:annotation-driven/>). Für die View kann dann der OpenEntityManagerInViewFilter verwendet werden, um Paging und Lazy-Loading zu realisieren:
	<filter>
	    <filter-name>OpenEntityManagerInViewFilter</filter-name>
	    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
	</filter>
	<filter-mapping>
	    <filter-name>OpenEntityManagerInViewFilter</filter-name>
		<servlet-name>Faces Servlet</servlet-name>
	</filter-mapping>

Der EntityManager kann allerdings die Session nur öffnen, wenn der Hibernate-Parameter dafür gesetzt ist (etwa in der persistence.xml):

<property name="hibernate.enable_lazy_load_no_trans" value="true"/>

Criteria Query#

In Hibernate sind die Criteria Querys eins der mächstigsten Instrumente, da sie rein durch ein Programm erzeugt werden können.
	Criteria criteria = ((Session)entityManager.getDelegate()).createCriteria(Rule.class);
	ProjectionList projections = Projections.projectionList();
	projections.add(Projections.alias(Projections.groupProperty(selector.property()), "goal"));
	projections.add(Projections.alias(Projections.rowCount(), "count"));
	criteria.setProjection(projections);
	criteria.add(Restrictions.like(selector.property(), text, MatchMode.ANYWHERE));
	criteria.addOrder(Order.desc("count"));
	criteria.setMaxResults(5);
	criteria.setResultTransformer(Transformers.aliasToBean(Suggestion.class));
	return criteria.list();

Unabhängige Subquery#

Subquerys können nur verwendet werden, wenn statt Restrictions über Property.forName(...) gegangen wird:
Criteria criteria = session.createCriteria(Transition.class);
DetachedCriteria subquery = DetachedCriteria.forClass(Participant.class);
subquery.add(Restrictions.eq("user", user));
subquery.setProjection(Projections.property("role"));
criteria.add(Property.forName("actor").in(subquery));

Abhängige Subquery#

Wenn Subquerys über Properties mit der Hauptquery verbunden sind, geht das nur über Aliase. Diese können beim erzeugen von Criterias und Subcriterias angegeben werden, sowie für Properties festgelegt.

UserType#

Durch Implementieren von org.hibernate.usertype.UserType können Mapper für eigene Datentypen geschrieben werden. Hibernate konvertiert diese dann von/zu primitiven Datenbanktypen.

Ein UserType kann auch automatisch angewandt werden, indem er mit entsprechenden Annotationen versehen wird:

@MappedSuperclass
@TypeDef(defaultForType = EnumSet.class, typeClass = EnumSetType.class)
public class EnumSetType<Type extends Enum<Type>> implements UserType, ParameterizedType {
    ...
}

Database Connections#

Hibernate bringt zwar ein Connection Management in der Default Configuration mit, das ist allerdings nicht besonders ausgereift. Inzwischen in das Hibernate Projekt integriert ist das C3P0-Connection Management:
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-c3p0</artifactId>
</dependency>

Der wichtigste Parameter besteht darin, in der persistence.xml das Connection-Verifying zu aktivieren:

<property name="hibernate.c3p0.testConnectionOnCheckout" value="true"/>