RESOLVED - issue BATCH-1340: Add Support for Native Queries to Jpa/Hibernate readers
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
@@ -25,6 +27,7 @@ import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemStreamException;
|
||||
import org.springframework.batch.item.database.support.AbstractHibernateQueryProvider;
|
||||
import org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -68,6 +71,10 @@ public class HibernateCursorItemReader<T> extends AbstractItemCountingItemStream
|
||||
|
||||
private String queryName = "";
|
||||
|
||||
private Map<String, Object> parameterValues;
|
||||
|
||||
private HibernateQueryProvider queryProvider;
|
||||
|
||||
private boolean useStatelessSession = true;
|
||||
|
||||
private boolean initialized = false;
|
||||
@@ -77,29 +84,53 @@ public class HibernateCursorItemReader<T> extends AbstractItemCountingItemStream
|
||||
public HibernateCursorItemReader() {
|
||||
setName(ClassUtils.getShortName(HibernateCursorItemReader.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* The parameter values to apply to a query (map of name:value).
|
||||
*
|
||||
* @param parameterValues the parameter values to set
|
||||
*/
|
||||
public void setParameterValues(Map<String, Object> parameterValues) {
|
||||
this.parameterValues = parameterValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open appropriate type of hibernate session and create the query.
|
||||
*/
|
||||
private Query createQuery() {
|
||||
|
||||
if (useStatelessSession) {
|
||||
statelessSession = sessionFactory.openStatelessSession();
|
||||
if (StringUtils.hasText(queryName)) {
|
||||
return statelessSession.getNamedQuery(queryName);
|
||||
if (queryProvider != null) {
|
||||
queryProvider.setStatelessSession(statelessSession);
|
||||
}
|
||||
else {
|
||||
return statelessSession.createQuery(queryString);
|
||||
if (StringUtils.hasText(queryName)) {
|
||||
return statelessSession.getNamedQuery(queryName);
|
||||
}
|
||||
else {
|
||||
return statelessSession.createQuery(queryString);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
statefulSession = sessionFactory.openSession();
|
||||
if (StringUtils.hasText(queryName)) {
|
||||
return statefulSession.getNamedQuery(queryName);
|
||||
if (queryProvider != null) {
|
||||
queryProvider.setSession(statefulSession);
|
||||
}
|
||||
else {
|
||||
return statefulSession.createQuery(queryString);
|
||||
if (StringUtils.hasText(queryName)) {
|
||||
return statefulSession.getNamedQuery(queryName);
|
||||
}
|
||||
else {
|
||||
return statefulSession.createQuery(queryString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if queryProvider is set use it to create a query
|
||||
return queryProvider.createQuery();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,10 +141,21 @@ public class HibernateCursorItemReader<T> extends AbstractItemCountingItemStream
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(sessionFactory, "session factory must be set");
|
||||
Assert.isTrue(fetchSize >= 0, "fetchSize must not be negative");
|
||||
Assert.isTrue(StringUtils.hasText(queryString) ^ StringUtils.hasText(queryName),
|
||||
"exactly one of queryString or queryName must be set");
|
||||
|
||||
Assert.state(sessionFactory!=null, "A SessionFactory must be provided");
|
||||
Assert.state(fetchSize >= 0, "fetchSize must not be negative");
|
||||
|
||||
if (queryProvider == null) {
|
||||
Assert.notNull(sessionFactory, "session factory must be set");
|
||||
Assert.state(StringUtils.hasText(queryString) ^ StringUtils.hasText(queryName),
|
||||
"queryString or queryName must be set");
|
||||
}
|
||||
// making sure that the appropriate (Hibernate) query provider is set
|
||||
else {
|
||||
Assert.state(queryProvider instanceof AbstractHibernateQueryProvider,
|
||||
"Hibernate query provider must be set");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,6 +172,13 @@ public class HibernateCursorItemReader<T> extends AbstractItemCountingItemStream
|
||||
this.queryString = queryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param queryProvider Hibernate query provider
|
||||
*/
|
||||
public void setQueryProvider(HibernateQueryProvider queryProvider) {
|
||||
this.queryProvider = queryProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be set only in uninitialized state.
|
||||
*
|
||||
@@ -193,24 +242,27 @@ public class HibernateCursorItemReader<T> extends AbstractItemCountingItemStream
|
||||
|
||||
/**
|
||||
* Open hibernate session and create a forward-only cursor for the
|
||||
* {@link #setQueryString(String)}.
|
||||
* query.
|
||||
*/
|
||||
protected void doOpen() throws Exception {
|
||||
Assert.state(!initialized, "Cannot open an already opened ItemReader, call close first");
|
||||
|
||||
cursor = createQuery().setFetchSize(fetchSize).scroll(ScrollMode.FORWARD_ONLY);
|
||||
Query query = createQuery();
|
||||
if (parameterValues!=null) {
|
||||
query.setProperties(parameterValues);
|
||||
}
|
||||
cursor = query.setFetchSize(fetchSize).scroll(ScrollMode.FORWARD_ONLY);
|
||||
|
||||
initialized = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void jumpToItem(int itemIndex) throws Exception {
|
||||
for(int i = 0; i < itemIndex; i++){
|
||||
for (int i = 0; i < itemIndex; i++) {
|
||||
cursor.next();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close the cursor and hibernate session.
|
||||
*/
|
||||
@@ -220,6 +272,7 @@ public class HibernateCursorItemReader<T> extends AbstractItemCountingItemStream
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
if (useStatelessSession) {
|
||||
if (statelessSession != null) {
|
||||
statelessSession.close();
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.StatelessSession;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Interface defining the functionality to be provided for generating queries
|
||||
* for use with Hibernate {@link ItemReader}s or other custom built artifacts.
|
||||
* </p>
|
||||
*
|
||||
* @author Anatoly Polinsky
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public interface HibernateQueryProvider {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Create the query object which type will be determined by the underline
|
||||
* implementation (e.g. Hibernate, JPA, etc.)
|
||||
* </p>
|
||||
*
|
||||
* @return created query
|
||||
*/
|
||||
Query createQuery();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Inject a {@link Session} that can be used as a factory for queries. The
|
||||
* state of the session is controlled by the caller (i.e. it should be
|
||||
* closed if necessary).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Use either this method or {@link #setStatelessSession(StatelessSession)}
|
||||
* </p>
|
||||
*
|
||||
* @param session the {@link Session} to set
|
||||
*/
|
||||
void setSession(Session session);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Inject a {@link StatelessSession} that can be used as a factory for
|
||||
* queries. The state of the session is controlled by the caller (i.e. it
|
||||
* should be closed if necessary).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Use either this method or {@link #setSession(Session)}
|
||||
* </p>
|
||||
*
|
||||
* @param session the {@link StatelessSession} to set
|
||||
*/
|
||||
void setStatelessSession(StatelessSession session);
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.database.support.AbstractJpaQueryProvider;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -90,12 +91,27 @@ public class JpaPagingItemReader<T> extends AbstractPagingItemReader<T> {
|
||||
|
||||
private String queryString;
|
||||
|
||||
private JpaQueryProvider queryProvider;
|
||||
|
||||
private Map<String, Object> parameterValues;
|
||||
|
||||
public JpaPagingItemReader() {
|
||||
setName(ClassUtils.getShortName(JpaPagingItemReader.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a query using an appropriate query provider (entityManager OR
|
||||
* queryProvider).
|
||||
*/
|
||||
private Query createQuery() {
|
||||
if (queryProvider == null) {
|
||||
return entityManager.createQuery(queryString);
|
||||
}
|
||||
else {
|
||||
return queryProvider.createQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
|
||||
this.entityManagerFactory = entityManagerFactory;
|
||||
}
|
||||
@@ -112,8 +128,15 @@ public class JpaPagingItemReader<T> extends AbstractPagingItemReader<T> {
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
super.afterPropertiesSet();
|
||||
Assert.notNull(entityManagerFactory);
|
||||
Assert.hasLength(queryString);
|
||||
|
||||
if (queryProvider == null) {
|
||||
Assert.notNull(entityManagerFactory);
|
||||
Assert.hasLength(queryString);
|
||||
}
|
||||
// making sure that the appropriate (JPA) query provider is set
|
||||
else {
|
||||
Assert.isTrue(queryProvider instanceof AbstractJpaQueryProvider, "JPA query provider must be set");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,13 +146,27 @@ public class JpaPagingItemReader<T> extends AbstractPagingItemReader<T> {
|
||||
this.queryString = queryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param queryProvider JPA query provider
|
||||
*/
|
||||
public void setQueryProvider(JpaQueryProvider queryProvider) {
|
||||
this.queryProvider = queryProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOpen() throws Exception {
|
||||
super.doOpen();
|
||||
|
||||
entityManager = entityManagerFactory.createEntityManager(jpaPropertyMap);
|
||||
if (entityManager == null) {
|
||||
throw new DataAccessResourceFailureException("Unable to obtain an EntityManager");
|
||||
}
|
||||
// set entityManager to queryProvider, so it participates
|
||||
// in JpaPagingItemReader's managed transaction
|
||||
if (queryProvider != null) {
|
||||
queryProvider.setEntityManager(entityManager);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,8 +179,7 @@ public class JpaPagingItemReader<T> extends AbstractPagingItemReader<T> {
|
||||
entityManager.flush();
|
||||
entityManager.clear();
|
||||
|
||||
Query query = entityManager.createQuery(queryString).setFirstResult(getPage() * getPageSize()).setMaxResults(
|
||||
getPageSize());
|
||||
Query query = createQuery().setFirstResult(getPage() * getPageSize()).setMaxResults(getPageSize());
|
||||
|
||||
if (parameterValues != null) {
|
||||
for (Map.Entry<String, Object> me : parameterValues.entrySet()) {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
|
||||
/**
|
||||
* <p>Interface defining the functionality to be provided for generating queries
|
||||
* for use with JPA {@link ItemReader}s or other custom built artifacts.</p>
|
||||
*
|
||||
* @author Anatoly Polinsky
|
||||
* @author Dave Syer
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public interface JpaQueryProvider {
|
||||
|
||||
/**
|
||||
* <p>Create the query object.</p>
|
||||
*
|
||||
* @return created query
|
||||
*/
|
||||
public Query createQuery();
|
||||
|
||||
/**
|
||||
* Provide an {@link EntityManager} for the query to be built.
|
||||
*
|
||||
* @param entityManager
|
||||
*/
|
||||
void setEntityManager(EntityManager entityManager);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.StatelessSession;
|
||||
import org.springframework.batch.item.database.HibernateQueryProvider;
|
||||
|
||||
/**
|
||||
* <p>Abstract Hibernate Query Provider to serve as a base class for all
|
||||
* Hibernate {@link Query} providers.</p>
|
||||
*
|
||||
* <p>The implementing provider can be configured to use either
|
||||
* {@link StatelessSession} sufficient for simple mappings without the need
|
||||
* to cascade to associated objects or standard Hibernate {@link Session}
|
||||
* for more advanced mappings or when caching is desired.</p>
|
||||
*
|
||||
* @author Anatoly Polinsky
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractHibernateQueryProvider implements HibernateQueryProvider {
|
||||
|
||||
private StatelessSession statelessSession;
|
||||
private Session statefulSession;
|
||||
|
||||
public void setStatelessSession(StatelessSession statelessSession) {
|
||||
this.statelessSession = statelessSession;
|
||||
}
|
||||
|
||||
public void setSession(Session statefulSession) {
|
||||
this.statefulSession = statefulSession;
|
||||
}
|
||||
|
||||
public boolean isStatelessSession() {
|
||||
return this.statefulSession==null && this.statelessSession!=null;
|
||||
}
|
||||
|
||||
protected StatelessSession getStatelessSession() {
|
||||
return statelessSession;
|
||||
}
|
||||
|
||||
protected Session getStatefulSession() {
|
||||
return statefulSession;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.springframework.batch.item.database.JpaQueryProvider;
|
||||
import org.springframework.batch.item.database.HibernateQueryProvider;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Abstract JPA Query Provider to serve as a base class for all JPA
|
||||
* {@link Query} providers.
|
||||
* </p>
|
||||
*
|
||||
* @author Anatoly Polinsky
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public abstract class AbstractJpaQueryProvider implements JpaQueryProvider, InitializingBean {
|
||||
|
||||
private EntityManager entityManager;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Public setter to override the entityManager that was created by this
|
||||
* {@link HibernateQueryProvider}. This is currently needed to allow
|
||||
* {@link HibernateQueryProvider} to participate in a user's managed transaction.
|
||||
* </p>
|
||||
*
|
||||
* @param entityManager
|
||||
*/
|
||||
public void setEntityManager(EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Getter for {@link EntityManager}
|
||||
* </p>
|
||||
*
|
||||
* @return entityManager the injected {@link EntityManager}
|
||||
*/
|
||||
protected EntityManager getEntityManager() {
|
||||
return entityManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.SQLQuery;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This query provider creates Hibernate {@link Query}s from injected native SQL
|
||||
* queries. This is useful if there is a need to utilize database-specific
|
||||
* features such as query hints, the CONNECT keyword in Oracle, etc.
|
||||
* </p>
|
||||
*
|
||||
* @author Anatoly Polinsky
|
||||
*
|
||||
* @param <E> entity returned by executing the query
|
||||
*/
|
||||
public class HibernateNativeQueryProvider<E> extends AbstractHibernateQueryProvider {
|
||||
|
||||
private String sqlQuery;
|
||||
|
||||
private Class<E> entityClass;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Create an {@link SQLQuery} from the session provided (preferring
|
||||
* stateless if both are available).
|
||||
* </p>
|
||||
*/
|
||||
public SQLQuery createQuery() {
|
||||
|
||||
if (isStatelessSession()) {
|
||||
return getStatelessSession().createSQLQuery(sqlQuery).addEntity(entityClass);
|
||||
}
|
||||
else {
|
||||
return getStatefulSession().createSQLQuery(sqlQuery).addEntity(entityClass);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSqlQuery(String sqlQuery) {
|
||||
this.sqlQuery = sqlQuery;
|
||||
}
|
||||
|
||||
public void setEntityClass(Class<E> entityClazz) {
|
||||
this.entityClass = entityClazz;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.isTrue(StringUtils.hasText(sqlQuery), "Native SQL query cannot be empty");
|
||||
Assert.notNull(entityClass, "Entity class cannot be NULL");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This query provider creates JPA {@link Query}s from injected native SQL
|
||||
* queries. This is useful if there is a need to utilize database-specific
|
||||
* features such as query hints, the CONNECT keyword in Oracle, etc.
|
||||
* </p>
|
||||
*
|
||||
* @author Anatoly Polinsky
|
||||
*
|
||||
* @param <E> entity returned by executing the query
|
||||
*/
|
||||
public class JpaNativeQueryProvider<E> extends AbstractJpaQueryProvider {
|
||||
|
||||
private Class<E> entityClass;
|
||||
|
||||
private String sqlQuery;
|
||||
|
||||
public Query createQuery() {
|
||||
return getEntityManager().createNativeQuery(sqlQuery, entityClass);
|
||||
}
|
||||
|
||||
public void setSqlQuery(String sqlQuery) {
|
||||
this.sqlQuery = sqlQuery;
|
||||
}
|
||||
|
||||
public void setEntityClass(Class<E> entityClazz) {
|
||||
this.entityClass = entityClazz;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.isTrue(StringUtils.hasText(sqlQuery), "Native SQL query cannot be empty");
|
||||
Assert.notNull(entityClass, "Entity class cannot be NULL");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.database.support.HibernateNativeQueryProvider;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
|
||||
|
||||
/**
|
||||
* @author Anatoly Polinsky
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class HibernateCursorItemReaderNativeQueryIntegrationTests extends HibernateCursorItemReaderIntegrationTests {
|
||||
|
||||
public ItemReader<Foo> createItemReader() throws Exception {
|
||||
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
|
||||
factoryBean.setDataSource(dataSource);
|
||||
factoryBean.setMappingLocations(new Resource[] { new ClassPathResource("Foo.hbm.xml", getClass()) });
|
||||
factoryBean.afterPropertiesSet();
|
||||
|
||||
SessionFactory sessionFactory = (SessionFactory) factoryBean.getObject();
|
||||
|
||||
|
||||
HibernateCursorItemReader<Foo> hibernateReader = new HibernateCursorItemReader<Foo>();
|
||||
|
||||
String nativeQuery = "select * from T_FOOS";
|
||||
|
||||
//creating a native query provider as it would be created in configuration
|
||||
HibernateNativeQueryProvider<Foo> queryProvider =
|
||||
new HibernateNativeQueryProvider<Foo>();
|
||||
|
||||
queryProvider.setSqlQuery(nativeQuery);
|
||||
queryProvider.setEntityClass(Foo.class);
|
||||
queryProvider.afterPropertiesSet();
|
||||
|
||||
hibernateReader.setQueryProvider(queryProvider);
|
||||
|
||||
//hibernateReader.setUseStatelessSession(isUseStatelessSession());
|
||||
hibernateReader.setSessionFactory(sessionFactory);
|
||||
hibernateReader.setSaveState(true);
|
||||
hibernateReader.afterPropertiesSet();
|
||||
|
||||
return hibernateReader;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.StatelessSession;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Tests for {@link HibernateCursorItemReader} using {@link StatelessSession}.
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "data-source-context.xml")
|
||||
public class HibernateCursorItemReaderParametersIntegrationTests extends AbstractDataSourceItemReaderIntegrationTests {
|
||||
|
||||
protected ItemReader<Foo> createItemReader() throws Exception {
|
||||
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
|
||||
factoryBean.setDataSource(dataSource);
|
||||
factoryBean.setMappingLocations(new Resource[] { new ClassPathResource("Foo.hbm.xml", getClass()) });
|
||||
factoryBean.afterPropertiesSet();
|
||||
|
||||
SessionFactory sessionFactory = (SessionFactory) factoryBean.getObject();
|
||||
|
||||
|
||||
HibernateCursorItemReader<Foo> hibernateReader = new HibernateCursorItemReader<Foo>();
|
||||
setQuery(hibernateReader);
|
||||
hibernateReader.setSessionFactory(sessionFactory);
|
||||
hibernateReader.setUseStatelessSession(isUseStatelessSession());
|
||||
hibernateReader.afterPropertiesSet();
|
||||
hibernateReader.setSaveState(true);
|
||||
|
||||
return hibernateReader;
|
||||
}
|
||||
|
||||
protected void setQuery(HibernateCursorItemReader<?> reader) {
|
||||
reader.setQueryString("from Foo where name like :name");
|
||||
reader.setParameterValues(Collections.singletonMap("name", (Object)"bar%"));
|
||||
}
|
||||
|
||||
protected boolean isUseStatelessSession() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -28,10 +30,11 @@ public class JpaPagingItemReaderIntegrationTests extends AbstractDataSourceItemR
|
||||
|
||||
EntityManagerFactory entityManagerFactory = factoryBean.getObject();
|
||||
|
||||
String jpqlQuery = "select f from Foo f";
|
||||
String jpqlQuery = "select f from Foo f where name like :name";
|
||||
|
||||
JpaPagingItemReader<Foo> inputSource = new JpaPagingItemReader<Foo>();
|
||||
inputSource.setQueryString(jpqlQuery);
|
||||
inputSource.setParameterValues(Collections.singletonMap("name", (Object)"bar%"));
|
||||
inputSource.setEntityManagerFactory(entityManagerFactory);
|
||||
inputSource.setPageSize(3);
|
||||
inputSource.afterPropertiesSet();
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.database.support.JpaNativeQueryProvider;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Anatoly Polinsky
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations={"JpaPagingItemReaderParameterTests-context.xml"})
|
||||
public class JpaPagingItemReaderNativeQueryIntegrationTests extends AbstractPagingItemReaderParameterTests {
|
||||
|
||||
@Autowired
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
protected ItemReader<Foo> getItemReader() throws Exception {
|
||||
|
||||
String sqlQuery = "select * from T_FOOS where value >= :limit";
|
||||
|
||||
JpaPagingItemReader<Foo> reader = new JpaPagingItemReader<Foo>();
|
||||
|
||||
//creating a native query provider as it would be created in configuration
|
||||
JpaNativeQueryProvider<Foo> queryProvider= new JpaNativeQueryProvider<Foo>();
|
||||
queryProvider.setSqlQuery(sqlQuery);
|
||||
queryProvider.setEntityClass(Foo.class);
|
||||
queryProvider.afterPropertiesSet();
|
||||
|
||||
reader.setParameterValues(Collections.<String, Object>singletonMap("limit", 3));
|
||||
reader.setEntityManagerFactory(entityManagerFactory);
|
||||
reader.setPageSize(3);
|
||||
reader.setQueryProvider(queryProvider);
|
||||
reader.afterPropertiesSet();
|
||||
reader.setSaveState(true);
|
||||
|
||||
return reader;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Anatoly Polinsky
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "../data-source-context.xml")
|
||||
public class HibernateNativeQueryProviderIntegrationTests {
|
||||
|
||||
protected DataSource dataSource;
|
||||
|
||||
protected HibernateNativeQueryProvider<Foo> hibernateQueryProvider;
|
||||
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
@Autowired
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
public HibernateNativeQueryProviderIntegrationTests() {
|
||||
hibernateQueryProvider = new HibernateNativeQueryProvider<Foo>();
|
||||
hibernateQueryProvider.setEntityClass(Foo.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
|
||||
factoryBean.setDataSource(dataSource);
|
||||
factoryBean.setMappingLocations(new Resource[] { new ClassPathResource("../Foo.hbm.xml", getClass()) });
|
||||
factoryBean.afterPropertiesSet();
|
||||
|
||||
sessionFactory = (SessionFactory) factoryBean.getObject();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void shouldRetrieveAndMapAllFoos() throws Exception {
|
||||
|
||||
String nativeQuery = "select * from T_FOOS";
|
||||
|
||||
hibernateQueryProvider.setSqlQuery(nativeQuery);
|
||||
hibernateQueryProvider.afterPropertiesSet();
|
||||
hibernateQueryProvider.setSession(sessionFactory.getCurrentSession());
|
||||
|
||||
Query query = hibernateQueryProvider.createQuery();
|
||||
|
||||
List<Foo> expectedFoos = new ArrayList<Foo>();
|
||||
|
||||
expectedFoos.add(new Foo(1, "bar1", 1));
|
||||
expectedFoos.add(new Foo(2, "bar2", 2));
|
||||
expectedFoos.add(new Foo(3, "bar3", 3));
|
||||
expectedFoos.add(new Foo(4, "bar4", 4));
|
||||
expectedFoos.add(new Foo(5, "bar5", 5));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Foo> actualFoos = query.list();
|
||||
|
||||
assertEquals(actualFoos, expectedFoos);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
|
||||
import org.hibernate.SQLQuery;
|
||||
import org.hibernate.StatelessSession;
|
||||
import org.hibernate.classic.Session;
|
||||
import org.junit.Test;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Anatoly Polinsky
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class HibernateNativeQueryProviderTests {
|
||||
|
||||
protected HibernateNativeQueryProvider<Foo> hibernateQueryProvider;
|
||||
|
||||
public HibernateNativeQueryProviderTests() {
|
||||
hibernateQueryProvider = new HibernateNativeQueryProvider<Foo>();
|
||||
hibernateQueryProvider.setEntityClass(Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateQueryWithStatelessSession() {
|
||||
String sqlQuery = "select * from T_FOOS";
|
||||
hibernateQueryProvider.setSqlQuery(sqlQuery);
|
||||
|
||||
StatelessSession session = createMock(StatelessSession.class);
|
||||
SQLQuery query = createMock(SQLQuery.class);
|
||||
|
||||
expect(session.createSQLQuery(sqlQuery)).andReturn(query);
|
||||
expect(query.addEntity(Foo.class)).andReturn(query);
|
||||
|
||||
replay(session, query);
|
||||
|
||||
hibernateQueryProvider.setStatelessSession(session);
|
||||
Assert.notNull(hibernateQueryProvider.createQuery());
|
||||
|
||||
verify(session, query);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateQueryWithStatefulSession() {
|
||||
String sqlQuery = "select * from T_FOOS";
|
||||
hibernateQueryProvider.setSqlQuery(sqlQuery);
|
||||
|
||||
Session session = createMock(Session.class);
|
||||
SQLQuery query = createMock(SQLQuery.class);
|
||||
|
||||
expect(session.createSQLQuery(sqlQuery)).andReturn(query);
|
||||
expect(query.addEntity(Foo.class)).andReturn(query);
|
||||
|
||||
replay(session, query);
|
||||
|
||||
hibernateQueryProvider.setSession(session);
|
||||
Assert.notNull(hibernateQueryProvider.createQuery());
|
||||
|
||||
verify(session, query);
|
||||
}
|
||||
|
||||
private static class Foo {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Anatoly Polinsky
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { "../JpaPagingItemReaderCommonTests-context.xml" })
|
||||
public class JpaNativeQueryProviderIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
private JpaNativeQueryProvider<Foo> jpaQueryProvider;
|
||||
|
||||
public JpaNativeQueryProviderIntegrationTests() {
|
||||
jpaQueryProvider = new JpaNativeQueryProvider<Foo>();
|
||||
jpaQueryProvider.setEntityClass(Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void shouldRetrieveAndMapAllFoos() throws Exception {
|
||||
|
||||
String sqlQuery = "select * from T_FOOS";
|
||||
jpaQueryProvider.setSqlQuery(sqlQuery);
|
||||
jpaQueryProvider.afterPropertiesSet();
|
||||
jpaQueryProvider.setEntityManager(entityManagerFactory.createEntityManager());
|
||||
|
||||
Query query = jpaQueryProvider.createQuery();
|
||||
|
||||
List<Foo> expectedFoos = new ArrayList<Foo>();
|
||||
|
||||
expectedFoos.add(new Foo(1, "bar1", 1));
|
||||
expectedFoos.add(new Foo(2, "bar2", 2));
|
||||
expectedFoos.add(new Foo(3, "bar3", 3));
|
||||
expectedFoos.add(new Foo(4, "bar4", 4));
|
||||
expectedFoos.add(new Foo(5, "bar5", 5));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Foo> actualFoos = query.getResultList();
|
||||
|
||||
assertEquals(actualFoos, expectedFoos);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void shouldExecuteParameterizedQuery() throws Exception {
|
||||
|
||||
String sqlQuery = "select * from T_FOOS where value >= :limit";
|
||||
|
||||
jpaQueryProvider.setSqlQuery(sqlQuery);
|
||||
jpaQueryProvider.afterPropertiesSet();
|
||||
jpaQueryProvider.setEntityManager(entityManagerFactory.createEntityManager());
|
||||
|
||||
Query query = jpaQueryProvider.createQuery();
|
||||
query.setParameter("limit", 3);
|
||||
|
||||
List<Foo> expectedFoos = new ArrayList<Foo>();
|
||||
|
||||
expectedFoos.add(new Foo(3, "bar3", 3));
|
||||
expectedFoos.add(new Foo(4, "bar4", 4));
|
||||
expectedFoos.add(new Foo(5, "bar5", 5));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Foo> actualFoos = query.getResultList();
|
||||
|
||||
assertEquals(actualFoos, expectedFoos);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2006-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Anatoly Polinsky
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class JpaNativeQueryProviderTests {
|
||||
|
||||
private JpaNativeQueryProvider<Foo> jpaQueryProvider;
|
||||
|
||||
public JpaNativeQueryProviderTests() {
|
||||
jpaQueryProvider = new JpaNativeQueryProvider<Foo>();
|
||||
jpaQueryProvider.setEntityClass(Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateQuery() {
|
||||
|
||||
String sqlQuery = "select * from T_FOOS where value >= :limit";
|
||||
jpaQueryProvider.setSqlQuery(sqlQuery);
|
||||
|
||||
EntityManager entityManager = createMock(EntityManager.class);
|
||||
Query query = createMock(Query.class);
|
||||
|
||||
expect(entityManager.createNativeQuery(sqlQuery, Foo.class)).andReturn(query);
|
||||
|
||||
replay(entityManager);
|
||||
|
||||
jpaQueryProvider.setEntityManager(entityManager);
|
||||
Assert.notNull(jpaQueryProvider.createQuery());
|
||||
|
||||
verify(entityManager);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user