Session session = (Session)entityManager.getDelegate(); ClassMetadata metadata = session.getSessionFactory().getClassMetadata(type); String keyName = metadata.getIdentifierPropertyName(); Class<?> keyType = metadata.getIdentifierType().getReturnedClass();
<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/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" lazy-init="true"> <property name="persistenceUnitName" value="subflowDb"/> <property name="jpaProperties"> <props> <prop key="hibernate.connection.url">jdbc:hsqldb:file:${project.build.directory}/hsql/data</prop> <prop key="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</prop> <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop> <prop key="hibernate.connection.username">sa</prop> <prop key="hibernate.connection.password"></prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean>
Allerdings ist es auch möglich, den LocalContainerEntityManagerFactoryBean lokal zu konfigurieren, sodass er z.B. aus einem JUnit-Test mit Spring heraus läuft:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitManager"> <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"> <property name="persistenceXmlLocations" value="classpath*:META-INF/persistence.xml"/> <property name="defaultDataSource" ref="dataSource"/> </bean> </property> </bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="100"/> <property name="maxIdle" value="30"/> <property name="maxWait" value="16000"/> <property name="minIdle" value="0"/> </bean>
Der Test sieht dann so aus:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:META-INF/testApplicationContext.xml") // @TransactionConfiguration(defaultRollback = false) public class SpringDBTest { @Test @Transactional public void test() { Criteria criteria = ((Session)entityManager.getDelegate()).createCriteria(Test.class); ... } }
<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 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();
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));
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 { ... }
<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"/>
In Oracle kann dies gelöst werden, indem dem Unique Key ein DEFERRABLE INITIALLY DEFERRED hinzugefügt wird. Dies führt dazu, dass der Unique Key erst beim Commit geprüft wird. Zu diesem Zeitpunkt ist die vorübergehende Inkonsistenz der Daten wieder beseitigt.