DATACMNS-29 - Extracted Repository marker interface from CrudRepository.

This change allows creating repository proxies without exposing CRUD methods at the same time. This essentially enables query-method-only repository interfaces.
This commit is contained in:
Oliver Gierke
2011-05-12 11:21:17 +02:00
parent d8c5bca4bd
commit 24394b4f1d
11 changed files with 153 additions and 140 deletions

View File

@@ -0,0 +1,114 @@
/*
* Copyright 2008-2010 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.data.repository;
import java.io.Serializable;
/**
* Interface for generic CRUD operations on a repository for a specific type.
*
* @author Oliver Gierke
* @author Eberhard Wolff
*/
@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
/**
* Saves a given entity. Use the returned instance for further operations as
* the save operation might have changed the entity instance completely.
*
* @param entity
* @return the saved entity
*/
T save(T entity);
/**
* Saves all given entities.
*
* @param entities
* @return
*/
Iterable<T> save(Iterable<? extends T> entities);
/**
* Retrives an entity by its primary key.
*
* @param id
* @return the entity with the given primary key or {@code null} if none
* found
* @throws IllegalArgumentException if primaryKey is {@code null}
*/
T findOne(ID id);
/**
* Returns whether an entity with the given id exists.
*
* @param id
* @return true if an entity with the given id exists, alse otherwise
* @throws IllegalArgumentException if primaryKey is {@code null}
*/
boolean exists(ID id);
/**
* Returns all instances of the type.
*
* @return all entities
*/
Iterable<T> findAll();
/**
* Returns the number of entities available.
*
* @return the number of entities
*/
long count();
/**
* Deletes the entity with the given id.
*
* @param id
*/
void delete(ID id);
/**
* Deletes a given entity.
*
* @param entity
*/
void delete(T entity);
/**
* Deletes the given entities.
*
* @param entities
*/
void delete(Iterable<? extends T> entities);
/**
* Deletes all entities managed by the repository.
*/
void deleteAll();
}

View File

@@ -23,7 +23,7 @@ import org.springframework.data.domain.Sort;
/**
* Extension of {@link Repository} to provide additional methods to retrieve
* Extension of {@link CrudRepository} to provide additional methods to retrieve
* entities using the pagination and sorting abstraction.
*
* @author Oliver Gierke
@@ -31,8 +31,9 @@ import org.springframework.data.domain.Sort;
* @see Pageable
* @see Page
*/
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID extends Serializable> extends
Repository<T, ID> {
CrudRepository<T, ID> {
/**
* Returns all entities sorted by the given options.

View File

@@ -1,113 +1,11 @@
/*
* Copyright 2008-2010 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.data.repository;
import java.io.Serializable;
/**
* Interface for generic CRUD operations on a repository for a specific type.
*
* @author Oliver Gierke
* @author Eberhard Wolff
*/
public interface Repository<T, ID extends Serializable> {
/**
* Saves a given entity. Use the returned instance for further operations as
* the save operation might have changed the entity instance completely.
*
* @param entity
* @return the saved entity
*/
T save(T entity);
/**
* Saves all given entities.
*
* @param entities
* @return
*/
Iterable<T> save(Iterable<? extends T> entities);
/**
* Retrives an entity by its primary key.
*
* @param id
* @return the entity with the given primary key or {@code null} if none
* found
* @throws IllegalArgumentException if primaryKey is {@code null}
*/
T findOne(ID id);
/**
* Returns whether an entity with the given id exists.
*
* @param id
* @return true if an entity with the given id exists, alse otherwise
* @throws IllegalArgumentException if primaryKey is {@code null}
*/
boolean exists(ID id);
/**
* Returns all instances of the type.
*
* @return all entities
*/
Iterable<T> findAll();
/**
* Returns the number of entities available.
*
* @return the number of entities
*/
long count();
/**
* Deletes the entity with the given id.
*
* @param id
*/
void delete(ID id);
/**
* Deletes a given entity.
*
* @param entity
*/
void delete(T entity);
/**
* Deletes the given entities.
*
* @param entities
*/
void delete(Iterable<? extends T> entities);
/**
* Deletes all entities managed by the repository.
*/
void deleteAll();
}

View File

@@ -28,23 +28,23 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.CrudRepository;
/**
* {@link org.springframework.core.convert.converter.Converter} to convert
* arbitrary input into domain classes managed by Spring Data {@link Repository}
* arbitrary input into domain classes managed by Spring Data {@link CrudRepository}
* s. The implementation uses a {@link ConversionService} in turn to convert the
* source type into the domain class' id type which is then converted into a
* domain class object by using a {@link Repository}.
* domain class object by using a {@link CrudRepository}.
*
* @author Oliver Gierke
*/
public class DomainClassConverter implements ConditionalGenericConverter,
ApplicationContextAware {
private final Map<EntityInformation<?, Serializable>, Repository<?, Serializable>> repositories =
new HashMap<EntityInformation<?, Serializable>, Repository<?, Serializable>>();
private final Map<EntityInformation<?, Serializable>, CrudRepository<?, Serializable>> repositories =
new HashMap<EntityInformation<?, Serializable>, CrudRepository<?, Serializable>>();
private final ConversionService service;
@@ -86,7 +86,7 @@ public class DomainClassConverter implements ConditionalGenericConverter,
EntityInformation<?, Serializable> info =
getRepositoryForDomainType(targetType.getType());
Repository<?, Serializable> repository = repositories.get(info);
CrudRepository<?, Serializable> repository = repositories.get(info);
Serializable id = service.convert(source, info.getIdType());
return repository.findOne(id);
}
@@ -146,9 +146,9 @@ public class DomainClassConverter implements ConditionalGenericConverter,
EntityInformation<Object, Serializable> metadata =
entry.getEntityInformation();
Class<Repository<Object, Serializable>> objectType =
Class<CrudRepository<Object, Serializable>> objectType =
entry.getRepositoryInterface();
Repository<Object, Serializable> repository =
CrudRepository<Object, Serializable> repository =
BeanFactoryUtils.beanOfType(context, objectType);
this.repositories.put(metadata, repository);

View File

@@ -21,35 +21,35 @@ import java.io.Serializable;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Generic {@link PropertyEditor} to map entities handled by a
* {@link Repository} to their id's and vice versa.
* {@link CrudRepository} to their id's and vice versa.
*
* @author Oliver Gierke
*/
public class DomainClassPropertyEditor<T, ID extends Serializable> extends
PropertyEditorSupport {
private final Repository<T, ID> repository;
private final CrudRepository<T, ID> repository;
private final EntityInformation<T, ID> information;
private final PropertyEditorRegistry registry;
/**
* Creates a new {@link DomainClassPropertyEditor} for the given
* {@link Repository}.
* {@link CrudRepository}, {@link EntityInformation} and {@link PropertyEditorRegistry}.
*
* @param repository
* @param information
* @param registry
*/
public DomainClassPropertyEditor(Repository<T, ID> repository,
EntityInformation<T, ID> information,
PropertyEditorRegistry registry) {
public DomainClassPropertyEditor(CrudRepository<T, ID> repository, EntityInformation<T, ID> information,
PropertyEditorRegistry registry) {
Assert.notNull(repository);
Assert.notNull(registry);

View File

@@ -26,7 +26,7 @@ import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.CrudRepository;
/**
@@ -56,8 +56,8 @@ import org.springframework.data.repository.Repository;
public class DomainClassPropertyEditorRegistrar implements
PropertyEditorRegistrar, ApplicationContextAware {
private final Map<EntityInformation<Object, Serializable>, Repository<Object, Serializable>> repositories =
new HashMap<EntityInformation<Object, Serializable>, Repository<Object, Serializable>>();
private final Map<EntityInformation<Object, Serializable>, CrudRepository<Object, Serializable>> repositories =
new HashMap<EntityInformation<Object, Serializable>, CrudRepository<Object, Serializable>>();
/*
@@ -69,11 +69,11 @@ public class DomainClassPropertyEditorRegistrar implements
*/
public void registerCustomEditors(PropertyEditorRegistry registry) {
for (Entry<EntityInformation<Object, Serializable>, Repository<Object, Serializable>> entry : repositories
for (Entry<EntityInformation<Object, Serializable>, CrudRepository<Object, Serializable>> entry : repositories
.entrySet()) {
EntityInformation<Object, Serializable> metadata = entry.getKey();
Repository<Object, Serializable> repository = entry.getValue();
CrudRepository<Object, Serializable> repository = entry.getValue();
DomainClassPropertyEditor<Object, Serializable> editor =
new DomainClassPropertyEditor<Object, Serializable>(
@@ -102,9 +102,9 @@ public class DomainClassPropertyEditorRegistrar implements
EntityInformation<Object, Serializable> metadata =
information.getEntityInformation();
Class<Repository<Object, Serializable>> objectType =
Class<CrudRepository<Object, Serializable>> objectType =
information.getRepositoryInterface();
Repository<Object, Serializable> repository =
CrudRepository<Object, Serializable> repository =
BeanFactoryUtils.beanOfType(context, objectType);
this.repositories.put(metadata, repository);

View File

@@ -6,7 +6,7 @@ import static org.junit.Assert.*;
import java.lang.reflect.Method;
import org.junit.Test;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.support.DefaultRepositoryMetadataUnitTests.DummyGenericRepositorySupport;
/**
@@ -35,12 +35,12 @@ public class DefaultRepositoryInformationUnitTests {
Method method = FooDao.class.getMethod("findOne", Long.class);
RepositoryMetadata metadata = new DefaultRepositoryMetadata(FooDao.class);
DefaultRepositoryInformation information = new DefaultRepositoryInformation(metadata, Repository.class);
DefaultRepositoryInformation information = new DefaultRepositoryInformation(metadata, CrudRepository.class);
assertThat(information.getBaseClassMethodFor(method), is(method));
}
private static interface FooDao extends Repository<User, Integer> {
private static interface FooDao extends CrudRepository<User, Integer> {
// Redeclared method
User findOne(Integer primaryKey);

View File

@@ -22,7 +22,7 @@ import java.io.Serializable;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.util.ClassUtils;
@@ -86,7 +86,7 @@ public class DefaultRepositoryMetadataUnitTests {
}
}
static interface UserRepository extends Repository<User, Integer> {
static interface UserRepository extends CrudRepository<User, Integer> {
}
@@ -117,12 +117,12 @@ public class DefaultRepositoryMetadataUnitTests {
}
static interface UserCustomExtendedRepository extends
Repository<User, Integer> {
CrudRepository<User, Integer> {
}
static abstract class DummyGenericRepositorySupport<T, ID extends Serializable>
implements Repository<T, ID> {
implements CrudRepository<T, ID> {
public T findOne(ID id) {
@@ -139,7 +139,7 @@ public class DefaultRepositoryMetadataUnitTests {
}
static interface GenericEntityRepository extends
Repository<GenericEntity<String>, Long> {
CrudRepository<GenericEntity<String>, Long> {
}
}

View File

@@ -35,7 +35,7 @@ import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.CrudRepository;
/**
@@ -186,7 +186,7 @@ public class DomainClassConverterUnitTests {
}
private static interface UserRepository extends Repository<User, Long> {
private static interface UserRepository extends CrudRepository<User, Long> {
}
}

View File

@@ -33,7 +33,7 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.CrudRepository;
/**
@@ -121,7 +121,7 @@ public class DomainClassPropertyEditorRegistrarUnitTests {
}
private static interface EntityRepository extends Repository<Entity, Long> {
private static interface EntityRepository extends CrudRepository<Entity, Long> {
}

View File

@@ -28,7 +28,7 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.data.domain.Persistable;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.CrudRepository;
/**
@@ -173,7 +173,7 @@ public class DomainClassPropertyEditorUnitTests {
*
* @author Oliver Gierke
*/
private static interface UserRepository extends Repository<User, Integer> {
private static interface UserRepository extends CrudRepository<User, Integer> {
}
}