2012-04-21 51 views
4

使用案例春数据仓库蒙戈常见::共享所有回购问题

方法,我试图用添加自定义行为所有仓库春数据的MongoDB功能。

该文档无助地描述了如何使用JPA进行连接。无论如何,与Mongo相当的配置设置。

我想为所有实体添加一个findByCategoryName(String categoryName)方法,因为我所有的实体都有一个Category。类别是DBRef对象,因此必须使用自定义查询。

下面是配置

<!-- Activate Spring Data MongoDB repository support --> 
<mongo:repositories base-package="com.domain.*.repo" repository-impl-postfix="CustomImpl" 
    factory-class="com.domain.commonrepo.CommonMongoRepoFactoryBean"/> 

<bean id="mappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" /> 

<mongo:mapping-converter mapping-context-ref="mappingContext"> 
    <mongo:custom-converters base-package="com.domain.mongo.converter" /> 
</mongo:mapping-converter> 

<bean id="entityInformationCreator" class="org.springframework.data.mongodb.repository.support.DefaultEntityInformationCreator"> 
    <constructor-arg name="mappingContext" ref="mappingContext" /> 
</bean> 

的相关部分。 。

的FactoryBean的

@NoRepositoryBean 
    public class CommonMongoRepoFactoryBean<T extends MongoRepository<?,?>, ID extends   
    Serializable> extends MongoRepositoryFactoryBean{ 

@Autowired 
private static MongoTemplate mongoTemplate; 

protected MongoRepositoryFactory getRepositoryFactory(Class<T> clazz) { 
    return new CommonMongoRepoFactory(clazz); 
} 

private static class CommonMongoRepoFactory extends MongoRepositoryFactory { 
    private Class clazz; 

    public CommonMongoRepoFactory(Class clazz) { 
     super(mongoTemplate); 
     this.clazz = clazz; 
    } 

    public CommonMongoRepoImpl getTargetRepository() { 
     return new CommonMongoRepoImpl(clazz); 
    } 

    public Class<?> getRepositoryClass() { 
     return CommonMongoRepoImpl.class; 
    } 
} 

我知道这是一个黑客攻击的一位,但没有文件它是一种痛苦。如果有人知道更好,请给我:-)

通用回购接口GitHub的链接

@NoRepositoryBean 
    public interface CommonMongoRepo<T, ID extends Serializable> extends MongoRepository<T,ID> { 

public List<T> findByCategoryName(String categoryName);   

实施

@NoRepositoryBean 
    public class CommonMongoRepoImpl<T, ID extends Serializable> extends SimpleMongoRepository<T,  
    ID> implements CommonMongoRepo<T, ID> { 

private Class<T> type; 

@Autowired 
private static MongoTemplate mongoOperations; 

@Autowired 
private static EntityInformationCreator entityInformationCreator; 

@Autowired 
private CategoryRepo categoryRepo; 

public CommonMongoRepoImpl(Class<T> type) { 
    super((MongoEntityInformation<T, ID>) entityInformationCreator.getEntityInformation(type), mongoOperations); 
} 

@Override 
public List<T> findByCategoryName(String categoryName) { 

    Category category = categoryRepo.findByName(categoryName); 

    return mongoOperations.find(query(where("categories.$id").is(category.getId())), type); 
} 

问题

现在,当我试图使用常用的方法我收到一个例外

否在“实体”中找到属性类别。我猜是什么时候mongo repo试图自动实现该方法。这是尽管我宣布豆作为@NoRepositoryBean

请帮助!不想将相同的自定义方法添加到所有实体

+0

参考文档使用JPA *作为示例*,因为我们不希望为每个商店重写公共存储库文档。所以如果你将所有Spring Data JPA相关类型与相应的Spring Data MongoDB类型('JpaRepository' - >'MongoRepository')交换,那么你应该没问题。唠叨不存在的文档无助于真正(尤其是如果它确实存在的话)。如果你真的关心,你总是可以自由地提交文档改进的拉取请求。您介意发布具体的存储库接口声明以及存储库基类实现吗? – 2012-04-22 09:16:26

+0

感谢您的回复。已经用代码更新了这个问题。我正在阅读Spring-Data-Mongo文档,因此期望Mongo示例在那里。这不仅仅是我,其他人也发现这个特殊的例子很难实现>> http://stackoverflow.com/questions/9842481/spring-data-mongodb-example-not-working – Nishant 2012-04-22 09:52:00

回答

3

以下是最佳解决方案!

第一步:
添加自定义方法到接口!
增加一个自定义的方法

#custom自接口

/** 
* Basic Repository for common custom methods 
* @author liangping 
*/ 

import java.io.Serializable; 

import org.springframework.data.domain.Page; 
import org.springframework.data.domain.Pageable; 
import org.springframework.data.mongodb.core.query.Query; 
import org.springframework.data.mongodb.repository.MongoRepository; 
import org.springframework.data.repository.NoRepositoryBean; 
import org.springframework.data.repository.PagingAndSortingRepository; 

@NoRepositoryBean 
public interface WootideRepositoryCustom <T, ID extends Serializable> 
     extends PagingAndSortingRepository<T, ID>, MongoRepository<T, ID> { 

     public Page<T> search(Query query, Pageable pageable); 
} 

实施

第二步:
添加实施您的自定义的方法!
实现你的自定义方法

/** 
* implement for wootide basic repository 
* @author liangping 
*/ 

import java.io.Serializable; 

import org.springframework.data.domain.Page; 
import org.springframework.data.domain.PageImpl; 
import org.springframework.data.domain.Pageable; 
import org.springframework.data.mongodb.core.MongoOperations; 
import org.springframework.data.mongodb.core.query.Query; 
import org.springframework.data.mongodb.repository.query.MongoEntityInformation; 
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository; 

public class WootideRepositoryImpl<T, ID extends Serializable> extends 
     SimpleMongoRepository<T, ID> implements WootideRepositoryCustom<T, ID> { 

    public WootideRepositoryImpl(MongoEntityInformation<T, ID> metadata, 
      MongoOperations mongoOperations) { 
     super(metadata, mongoOperations); 
    } 

    @Override 
    public Page<T> search(Query query, Pageable pageable) { 
     long total = this.getMongoOperations().count(query, this.getEntityInformation().getJavaType()); 
     return new PageImpl<T>(this.getMongoOperations().find(query.with(pageable), this.getEntityInformation().getJavaType()), pageable, total); 
    } 

} 

创建自定义库中的新工厂

/** 
* Repository Factory for all Subrepository 
* @author liangping 
*/ 

import java.io.Serializable; 

import org.springframework.data.mongodb.core.MongoOperations; 
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity; 
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; 
import org.springframework.data.mongodb.repository.MongoRepository; 
import org.springframework.data.mongodb.repository.query.MongoEntityInformation; 
import org.springframework.data.mongodb.repository.support.MappingMongoEntityInformation; 
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory; 
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean; 
import org.springframework.data.repository.core.RepositoryMetadata; 
import org.springframework.data.repository.core.support.RepositoryFactorySupport; 
import org.springframework.data.util.ClassTypeInformation; 
import org.springframework.data.util.TypeInformation; 

public class WootideRepositoryFactoryBean<R extends MongoRepository<T, I>, T, I extends Serializable> 
     extends MongoRepositoryFactoryBean<R, T, I> { 

    @Override 
    protected RepositoryFactorySupport getFactoryInstance(
      MongoOperations operations) { 
     return new WootideMongoRepositoryFactory<T,I>(operations); 
    } 

    private static class WootideMongoRepositoryFactory<T, ID extends Serializable> 
      extends MongoRepositoryFactory { 

     private MongoOperations mongo; 
     public WootideMongoRepositoryFactory(MongoOperations mongoOperations) { 
      super(mongoOperations); 
      this.mongo = mongoOperations; 
     } 

     @SuppressWarnings("unchecked") 
     protected Object getTargetRepository(RepositoryMetadata metadata) { 

      TypeInformation<T> information = ClassTypeInformation.from((Class<T>)metadata.getDomainType()); 
      MongoPersistentEntity<T> pe = new BasicMongoPersistentEntity<T>(information); 
      MongoEntityInformation<T,ID> mongometa = new MappingMongoEntityInformation<T, ID>(pe); 

      return new WootideRepositoryImpl<T, ID>(mongometa, mongo); 
     } 

     protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) { 
      return WootideRepositoryCustom.class; 
     } 
    } 
} 

让它工作

<mongo:repositories base-package="com.***.mongodb" 
factory-class="com.***.mongodb.custom.WootideRepositoryFactoryBean"/> 

祝您好运!祝你好运!

0

有点迟了,但here是为Spring Web应用项目做到这一点的示例代码。要点是:在控制器中使用

  1. 接口
  2. 实现在一个单独的类,它从基础
  3. 基本实现规定,任何其他控制器可以只用一个快速的继承
  4. 使用常用的方法继承完成