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"/>