!!!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/>
}}}

!!!Spring Open EntityManager once in View Pattern
web.xml:
{{{
	<filter>
		<filter-name>EntityManagerFilter</filter-name>
		<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>EntityManagerFilter</filter-name>
		<servlet-name>Faces Servlet</servlet-name>
	</filter-mapping>
}}}

!!!Spring Open EntityManager in Session
Es ist eher 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.

Dennoch hier der Code:

{{{
public class OpenEntityManagerInSessionFilter extends OncePerRequestFilter {
	public static final String ENTITY_MANAGER_FACTORY_NAME = "entityManagerFactory";
	public static final String ENTITY_MANAGER_NAME = "entityManager";

	private String entityManagerFactoryBeanName = ENTITY_MANAGER_FACTORY_NAME;

	public void setEntityManagerFactoryBeanName(String entityManagerFactoryBeanName) {
		this.entityManagerFactoryBeanName = entityManagerFactoryBeanName;
	}

	public String getEntityManagerFactoryBeanName() {
		return entityManagerFactoryBeanName;
	}

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		EntityManagerFactory entityManagerFactory = lookupEntityManagerFactory();
		boolean participate = false;
		try {
			if (TransactionSynchronizationManager.hasResource(entityManagerFactory)) {
				participate = true;
			} else {
				EntityManager entityManager = (EntityManager)request.getSession().getAttribute(ENTITY_MANAGER_NAME);
				if (entityManager == null) {
					entityManager = entityManagerFactory.createEntityManager();
					request.getSession().setAttribute(ENTITY_MANAGER_NAME, entityManager);
				}
				TransactionSynchronizationManager.bindResource(
					entityManagerFactory, new EntityManagerHolder(entityManager));
			}
			filterChain.doFilter(request, response);
		} finally {
			if (!participate)
				TransactionSynchronizationManager.unbindResource(entityManagerFactory);
		}
	}

	protected EntityManagerFactory lookupEntityManagerFactory() {
		WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
		return (EntityManagerFactory) wac.getBean(getEntityManagerFactoryBeanName(), EntityManagerFactory.class);
	}
}
}}}

!!!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|Hibernate EnumSet] 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 {
    ...
}
}}}