DATAJPA-32 - Adopted changes for DATACMNS-17.

This commit is contained in:
Oliver Gierke
2011-02-24 17:30:03 +00:00
parent 44979ac246
commit 99a05d5bb0
10 changed files with 128 additions and 247 deletions

View File

@@ -20,6 +20,7 @@ import java.io.Serializable;
import javax.persistence.EntityManager;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.support.EntityMetadata;
/**
@@ -35,10 +36,10 @@ public class CustomGenericJpaRepository<T, ID extends Serializable> extends
* @param domainClass
* @param entityManager
*/
public CustomGenericJpaRepository(Class<T> domainClass,
public CustomGenericJpaRepository(EntityMetadata<T> metadata,
EntityManager entityManager) {
super(domainClass, entityManager);
super(metadata, entityManager);
}

View File

@@ -15,12 +15,15 @@
*/
package org.springframework.data.jpa.repository.custom;
import static org.mockito.Mockito.*;
import java.io.Serializable;
import javax.persistence.EntityManager;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.repository.support.RepositorySupport;
import org.springframework.data.repository.support.EntityMetadata;
import org.springframework.data.repository.support.RepositoryMetadata;
/**
@@ -48,10 +51,15 @@ public class CustomGenericJpaRepositoryFactory extends JpaRepositoryFactory {
* #getTargetRepository(java.lang.Class, javax.persistence.EntityManager)
*/
@Override
protected <T, ID extends Serializable> RepositorySupport<T, ID> getTargetRepository(
Class<T> domainClass, Class<?> repositoryInterface, EntityManager em) {
@SuppressWarnings("unchecked")
protected Object getTargetRepository(RepositoryMetadata metadata,
EntityManager em) {
return new CustomGenericJpaRepository<T, ID>(domainClass, em);
EntityMetadata<Object> entityMetadata = mock(EntityMetadata.class);
when(entityMetadata.getJavaType()).thenReturn(
(Class<Object>) metadata.getDomainClass());
return new CustomGenericJpaRepository<Object, Serializable>(
entityMetadata, em);
}
@@ -59,13 +67,11 @@ public class CustomGenericJpaRepositoryFactory extends JpaRepositoryFactory {
* (non-Javadoc)
*
* @see
* org.springframework.data.jpa.repository.support.GenericJpaRepositoryFactory
* #getRepositoryClass()
* org.springframework.data.repository.support.RepositoryFactorySupport#
* getRepositoryBaseClass()
*/
@Override
@SuppressWarnings("rawtypes")
protected Class<? extends RepositorySupport> getRepositoryClass(
Class<?> repositoryInterface) {
protected Class<?> getRepositoryBaseClass(Class<?> repositoryInterface) {
return CustomGenericJpaRepository.class;
}

View File

@@ -15,24 +15,16 @@
*/
package org.springframework.data.jpa.repository.support;
import static org.mockito.Mockito.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.hibernate.ejb.HibernateEntityManager;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.jpa.repository.config.AbstractRepositoryConfigTests;
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanReference;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
@@ -41,83 +33,40 @@ import org.springframework.test.context.ContextConfiguration;
*
* @author Oliver Gierke
*/
@ContextConfiguration(locations = "classpath:multiple-entity-manager-context.xml")
public class EntityManagerFactoryRefUnitTests extends
AbstractRepositoryConfigTests {
@Autowired
@Qualifier("entityManagerFactory")
EntityManagerFactory first;
@Autowired
@Qualifier("secondEntityManagerFactory")
EntityManagerFactory second;
public class EntityManagerFactoryRefUnitTests {
@Test
public void repositoriesGetTheSecondEntityManagerFactoryInjected()
throws Exception {
public void repositoriesGetTheSecondEntityManagerFactoryInjected2() {
verify(first, never()).createEntityManager();
verify(second, atLeastOnce()).createEntityManager();
XmlBeanFactory factory =
new XmlBeanFactory(new ClassPathResource(
"multiple-entity-manager-context.xml"));
BeanDefinition bean = factory.getBeanDefinition("userRepository");
Object value = getPropertyValue(bean, "entityManager");
assertTrue(value instanceof BeanDefinition);
BeanDefinition emCreator = (BeanDefinition) value;
BeanReference reference = getConstructorBeanReference(emCreator, 0);
assertThat(reference.getBeanName(), is("secondEntityManagerFactory"));
}
/**
* A simple No-Op {@link PersistenceExceptionTranslator} to be configured in
* the test case's config file as it is required.
*
* @author Oliver Gierke
*/
static class NoOpPersistenceExceptionTranslator implements
PersistenceExceptionTranslator {
public DataAccessException translateExceptionIfPossible(
RuntimeException ex) {
private Object getPropertyValue(BeanDefinition definition,
String propertyName) {
return null;
}
return definition.getPropertyValues().getPropertyValue(propertyName)
.getValue();
}
/**
* {@link BeanPostProcessor} to configure the mock
* {@link EntityManagerFactory} instances. {@code entityManagerFactory} is
* configured to be never invoked, {@code secondEntityManagerFactory} is
* configured to be invoked at least once.
*
* @author Oliver Gierke
*/
static class MockPreparingBeanPostProcessor implements BeanPostProcessor {
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
private BeanReference getConstructorBeanReference(
BeanDefinition definition, int index) {
if ("secondEntityManagerFactory".equals(beanName)) {
EntityManagerFactory entityManagerFactory =
(EntityManagerFactory) bean;
EntityManager em = mock(HibernateEntityManager.class);
when(entityManagerFactory.createEntityManager()).thenReturn(em);
EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) bean;
when(info.getEntityManagerInterface()).thenAnswer(
new Answer<Class<?>>() {
public Class<?> answer(InvocationOnMock invocation)
throws Throwable {
return HibernateEntityManager.class;
}
});
}
return bean;
}
public Object postProcessBeforeInitialization(Object bean,
String beanName) throws BeansException {
return bean;
}
Object value =
definition.getConstructorArgumentValues()
.getIndexedArgumentValues().get(index).getValue();
assertTrue(value instanceof BeanReference);
return (BeanReference) value;
}
}

View File

@@ -32,7 +32,7 @@ import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.jpa.domain.sample.User;
import org.springframework.data.domain.Persistable;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -124,50 +124,18 @@ public class JpaRepositoryFactoryBeanUnitTests {
factory.afterPropertiesSet();
}
/**
* Asserts that the factory recognized configured repository classes that
* contain custom method but no custom implementation could be found.
* Furthremore the exception has to contain the name of the repository
* interface as for a large repository configuration it's hard to find out
* where this error occured.
*
* @throws Exception
*/
@Test
public void capturesMissingCustomImplementationAndProvidesInterfacename()
throws Exception {
JpaRepositoryFactoryBean<SampleRepository> factory =
JpaRepositoryFactoryBean.create(SampleRepository.class, entityManager);
try {
factory.afterPropertiesSet();
fail("Expected IllegalArgumentException!");
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage()
.contains(SampleRepository.class.getName()));
}
}
private interface SimpleSampleRepository extends
JpaRepository<User, Integer> {
}
/**
* Sample interface to contain a custom method.
* Helper class to make the factory use {@link PersistableMetadata} .
*
* @author Oliver Gierke
*/
private interface SampleCustomRepository {
void someSampleMethod();
}
private interface SampleRepository extends JpaRepository<User, Integer>,
SampleCustomRepository {
@SuppressWarnings("serial")
private static abstract class User implements Persistable<Long> {
}
}

View File

@@ -26,7 +26,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.jpa.domain.sample.User;
import org.springframework.data.domain.Persistable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.custom.CustomGenericJpaRepositoryFactory;
import org.springframework.data.jpa.repository.custom.UserCustomExtendedRepository;
@@ -176,4 +176,14 @@ public class JpaRepositoryFactoryUnitTests {
SampleCustomRepository {
}
/**
* Helper class to make the factory use {@link PersistableMetadata} .
*
* @author Oliver Gierke
*/
@SuppressWarnings("serial")
private static abstract class User implements Persistable<Long> {
}
}