DATAJPA-32 - Adopted changes for DATACMNS-17.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2011 the original author or authors.
|
||||
* Copyright 2011 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.
|
||||
@@ -23,38 +23,35 @@ import javax.persistence.metamodel.EntityType;
|
||||
import javax.persistence.metamodel.Metamodel;
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
|
||||
import org.springframework.data.repository.support.IdAware;
|
||||
import org.springframework.data.repository.support.IsNewAware;
|
||||
import org.springframework.data.repository.support.AbstractEntityMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of {@link IsNewAware} and {@link IdAware} that uses JPA
|
||||
* {@link Metamodel} to find the domain class' id field.
|
||||
* Implementation of {@link EntityInformation} that uses JPA {@link Metamodel}
|
||||
* to find the domain class' id field.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class JpaMetamodelEntityInformation implements IsNewAware, IdAware {
|
||||
public class JpaMetamodelEntityMetadata<T> extends AbstractEntityMetadata<T> {
|
||||
|
||||
private final Member member;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link JpaMetamodelEntityInformation} for the given domain
|
||||
* Creates a new {@link JpaMetamodelEntityMetadata} for the given domain
|
||||
* class and {@link Metamodel}.
|
||||
*
|
||||
* @param domainClass
|
||||
* @param metamodel
|
||||
*/
|
||||
public JpaMetamodelEntityInformation(Class<?> domainClass,
|
||||
Metamodel metamodel) {
|
||||
public JpaMetamodelEntityMetadata(Class<T> domainClass, Metamodel metamodel) {
|
||||
|
||||
super(domainClass);
|
||||
|
||||
Assert.notNull(domainClass);
|
||||
Assert.notNull(metamodel);
|
||||
|
||||
EntityType<?> type = metamodel.entity(domainClass);
|
||||
|
||||
SingularAttribute<?, ?> idAttribute =
|
||||
type.getId(type.getIdType().getJavaType());
|
||||
this.member = idAttribute.getJavaMember();
|
||||
@@ -74,19 +71,6 @@ public class JpaMetamodelEntityInformation implements IsNewAware, IdAware {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.IsNewAware#isNew(java.lang
|
||||
* .Object)
|
||||
*/
|
||||
public boolean isNew(Object entity) {
|
||||
|
||||
return getId(entity) == null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the given {@link Member} of the given {@link Object}
|
||||
* .
|
||||
@@ -15,16 +15,17 @@
|
||||
*/
|
||||
package org.springframework.data.jpa.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.springframework.data.domain.Persistable;
|
||||
import org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy;
|
||||
import org.springframework.data.jpa.repository.query.QueryExtractor;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
import org.springframework.data.repository.support.EntityMetadata;
|
||||
import org.springframework.data.repository.support.PersistableEntityMetadata;
|
||||
import org.springframework.data.repository.support.RepositoryFactorySupport;
|
||||
import org.springframework.data.repository.support.RepositorySupport;
|
||||
import org.springframework.data.repository.support.RepositoryMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -60,11 +61,9 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
|
||||
* getTargetRepository(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
protected <T, ID extends Serializable> RepositorySupport<T, ID> getTargetRepository(
|
||||
Class<T> domainClass, Class<?> repositoryInterface) {
|
||||
protected Object getTargetRepository(RepositoryMetadata metadata) {
|
||||
|
||||
return getTargetRepository(domainClass, repositoryInterface,
|
||||
entityManager);
|
||||
return getTargetRepository(metadata, entityManager);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,16 +73,40 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
|
||||
*
|
||||
* @param <T>
|
||||
* @param <ID>
|
||||
* @param domainClass
|
||||
* @param entityManager
|
||||
* @see #getTargetRepository(Class, Class)
|
||||
* @see #getTargetRepository(RepositoryMetadata)
|
||||
* @return
|
||||
*/
|
||||
protected <T, ID extends Serializable> RepositorySupport<T, ID> getTargetRepository(
|
||||
Class<T> domainClass, Class<?> repositoryInterface,
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
protected Object getTargetRepository(RepositoryMetadata metadata,
|
||||
EntityManager entityManager) {
|
||||
|
||||
return new SimpleJpaRepository<T, ID>(domainClass, entityManager);
|
||||
return new SimpleJpaRepository(createEntityInformation(
|
||||
metadata.getDomainClass(), entityManager), entityManager);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link EntityMetadata} instance for the given domain class
|
||||
* and {@link EntityManager}. Default implementation will use a
|
||||
* {@link PersistableMetadata} for domain classes implementing
|
||||
* {@link Persistable} and fall back to the JPA meta model though
|
||||
* {@link JpaMetamodelEntityInformation} otherwise.
|
||||
*
|
||||
* @param domainClass
|
||||
* @param em
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected EntityMetadata<?> createEntityInformation(Class<?> domainClass,
|
||||
EntityManager em) {
|
||||
|
||||
if (Persistable.class.isAssignableFrom(domainClass)) {
|
||||
return new PersistableEntityMetadata();
|
||||
} else {
|
||||
return new JpaMetamodelEntityMetadata(domainClass,
|
||||
em.getMetamodel());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,12 +115,10 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.support.RepositoryFactorySupport#
|
||||
* getRepositoryClass(java.lang.Class)
|
||||
* getRepositoryBaseClass()
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
protected Class<? extends RepositorySupport> getRepositoryClass(
|
||||
Class<?> repositoryInterface) {
|
||||
protected Class<?> getRepositoryBaseClass(Class<?> repositoryInterface) {
|
||||
|
||||
return SimpleJpaRepository.class;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
@@ -33,14 +32,11 @@ import javax.persistence.criteria.Root;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Persistable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.support.IsNewAware;
|
||||
import org.springframework.data.repository.support.PersistableEntityInformation;
|
||||
import org.springframework.data.repository.support.RepositorySupport;
|
||||
import org.springframework.data.repository.support.EntityMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -54,9 +50,10 @@ import org.springframework.util.Assert;
|
||||
* @param <ID> the type of the entity's identifier
|
||||
*/
|
||||
@org.springframework.stereotype.Repository
|
||||
public class SimpleJpaRepository<T, ID extends Serializable> extends
|
||||
RepositorySupport<T, ID> implements JpaRepository<T, ID> {
|
||||
public class SimpleJpaRepository<T, ID extends Serializable> implements
|
||||
JpaRepository<T, ID> {
|
||||
|
||||
private final EntityMetadata<T> entityInformation;
|
||||
private final EntityManager em;
|
||||
private final PersistenceProvider provider;
|
||||
|
||||
@@ -65,19 +62,26 @@ public class SimpleJpaRepository<T, ID extends Serializable> extends
|
||||
* Creates a new {@link SimpleJpaRepository} to manage objects of the given
|
||||
* domain type.
|
||||
*
|
||||
* @param domainClass
|
||||
* @param entityInformation
|
||||
* @param entityManager
|
||||
*/
|
||||
public SimpleJpaRepository(Class<T> domainClass, EntityManager entityManager) {
|
||||
|
||||
super(domainClass);
|
||||
public SimpleJpaRepository(EntityMetadata<T> entityInformation,
|
||||
EntityManager entityManager) {
|
||||
|
||||
Assert.notNull(entityInformation);
|
||||
Assert.notNull(entityManager);
|
||||
this.entityInformation = entityInformation;
|
||||
this.em = entityManager;
|
||||
this.provider = PersistenceProvider.fromEntityManager(entityManager);
|
||||
}
|
||||
|
||||
|
||||
private Class<T> getDomainClass() {
|
||||
|
||||
return entityInformation.getJavaType();
|
||||
}
|
||||
|
||||
|
||||
private String getDeleteAllQueryString() {
|
||||
|
||||
return getQueryString(DELETE_ALL_QUERY_STRING, getDomainClass());
|
||||
@@ -94,22 +98,6 @@ public class SimpleJpaRepository<T, ID extends Serializable> extends
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Factory method to create {@link SimpleJpaRepository} instances.
|
||||
*
|
||||
* @param domainClass the domain class to handle
|
||||
* @param entityManager the {@link EntityManager} backing the repository
|
||||
* @param <T> the type of the entity to handle
|
||||
* @param <ID> the type of the entity's identifier
|
||||
* @return
|
||||
*/
|
||||
public static <T, ID extends Serializable> Repository<T, ID> create(
|
||||
Class<T> domainClass, EntityManager entityManager) {
|
||||
|
||||
return new SimpleJpaRepository<T, ID>(domainClass, entityManager);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -303,7 +291,7 @@ public class SimpleJpaRepository<T, ID extends Serializable> extends
|
||||
*/
|
||||
public T save(T entity) {
|
||||
|
||||
if (getIsNewStrategy().isNew(entity)) {
|
||||
if (entityInformation.isNew(entity)) {
|
||||
em.persist(entity);
|
||||
return entity;
|
||||
} else {
|
||||
@@ -361,41 +349,6 @@ public class SimpleJpaRepository<T, ID extends Serializable> extends
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.jpa.repository.support.JpaRepositorySupport#
|
||||
* createIsNewStrategy(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
protected final IsNewAware createIsNewStrategy(Class<?> domainClass) {
|
||||
|
||||
return createIsNewStrategy(domainClass, em);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link IsNewAware} instance for the given domain class and
|
||||
* {@link EntityManager}.
|
||||
*
|
||||
* @param domainClass
|
||||
* @param em
|
||||
* @return
|
||||
*/
|
||||
protected IsNewAware createIsNewStrategy(Class<?> domainClass,
|
||||
EntityManager em) {
|
||||
|
||||
if (Persistable.class.isAssignableFrom(domainClass)) {
|
||||
return new PersistableEntityInformation();
|
||||
} else {
|
||||
EntityManagerFactory emf = em.getEntityManagerFactory();
|
||||
return new JpaMetamodelEntityInformation(domainClass,
|
||||
emf.getMetamodel());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads the given {@link TypedQuery} into a {@link Page} applying the given
|
||||
* {@link Pageable} and {@link Specification}.
|
||||
|
||||
@@ -5,6 +5,7 @@ Changes in version 1.0.0.M2
|
||||
----------------------------------------
|
||||
* Added support for 'Distinct' (DATACMNS-15)
|
||||
* Added support for 'In' and 'NotIn' (DATAJPA-30)
|
||||
* Adapted new metadata API (DATAJPA-32, DATACMNS-17)
|
||||
|
||||
Changes in version 1.0.0.M1 (2011-02-10) - https://jira.springsource.org/browse/DATAJPA/fixforversion/11786
|
||||
----------------------------------------
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,27 +7,15 @@
|
||||
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
|
||||
|
||||
<bean id="entityManagerFactory" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg value="org.hibernate.ejb.HibernateEntityManagerFactory" />
|
||||
<constructor-arg ref="implementEntityManagerFactoryInfo" />
|
||||
<constructor-arg value="javax.persistence.EntityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="secondEntityManagerFactory" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg value="org.hibernate.ejb.HibernateEntityManagerFactory" />
|
||||
<constructor-arg ref="implementEntityManagerFactoryInfo" />
|
||||
<constructor-arg value="javax.persistence.EntityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="settings" class="org.mockito.Mockito" factory-method="withSettings" />
|
||||
<bean id="implementEntityManagerFactoryInfo" factory-bean="settings" factory-method="extraInterfaces">
|
||||
<constructor-arg value="org.springframework.orm.jpa.EntityManagerFactoryInfo" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.data.jpa.repository.support.EntityManagerFactoryRefUnitTests$MockPreparingBeanPostProcessor" />
|
||||
<bean class="org.springframework.data.jpa.repository.support.EntityManagerFactoryRefUnitTests$NoOpPersistenceExceptionTranslator" />
|
||||
|
||||
<jpa:repositories base-package="org.springframework.data.jpa.repository.sample" entity-manager-factory-ref="secondEntityManagerFactory">
|
||||
<jpa:repository id="userRepository" />
|
||||
<jpa:repository id="roleRepository" />
|
||||
<jpa:repository id="auditableUserRepository"/>
|
||||
</jpa:repositories>
|
||||
|
||||
</beans>
|
||||
|
||||
Reference in New Issue
Block a user