Spring Data Mongo |使用@Query方法失败的动态集合名称

时间:2014-12-02 15:30:05

标签: spring-data-mongodb

考虑一个简单的域类: -

@Document(collection = "#{T(demo.TenantGenerator).tenant()}Employee")
public class Employee  implements Serializable{

    /**
     * serialVersionUID
     */
    private static final long serialVersionUID = -6236812201549032402L;

    @Id
    private String id;

    protected String name;

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }


}

这里我使用SpEL定位动态集合名称,以静态方法为目标: -

public class TenantGenerator {

    public static String tenant = "";

    public static final String tenant(){
        return tenant;
    }
}

这就是我的存储库界面的样子: -

public interface EmployeeRepository extends MongoRepository<Employee,String> {

    @Query(value="{'name':?0}")
    public List<Employee> someMethod(String id);
}

我的测试代码: -

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class ApplicationTests {

    @Autowired
    private EmployeeRepository repo;

    @Autowired
    private MongoTemplate template;

    @Test
    public void contextLoads() {

        // Set the collection with ABC
        TenantGenerator.tenant = "ABC";

        Employee e = new Employee();
        e.setName("test");

        repo.save(e);

        Employee ee = new Employee();
        e.setName("test");

        repo.save(ee);


        List<Employee> findAll = repo.findAll();
        System.out.println(findAll.size());

        Employee eee = new Employee();
        e.setName("test");


        template.save(eee,"customercoll");

        System.out.println(repo.someMethod("test"));

        //Set collection name with XYZ
        TenantGenerator.tenant = "XYZ";

        System.out.println(repo.someMethod("test")); // PROBLEM  this should try to get from XYZ. But instead tries to fetch from ABC itself
        System.out.println(repo.findAll());

    }

}

问题

在运行时正确选择集合名称,除非我的存储库中有@Query注释的方法。

在尝试调试Spring Data Mongo代码时,我发现对于@Query带注释的方法,org.springframework.data.mongodb.repository.query.MongoQueryMethod会在属性org.springframework.data.mongodb.repository.query.MongoQueryMethod.metadata中缓存其中的集合信息。

因此,在查询执行期间尝试获取org.springframework.data.mongodb.repository.query.MongoQueryMethod.getEntityInformation()时,第二次使用SpEL不会获取集合名称。

相对的一段代码: -

@Override
@SuppressWarnings("unchecked")
public MongoEntityMetadata<?> getEntityInformation() {

    if (metadata == null) { // !!!THIS IS PROBLEM FOR ME!!!!

        Class<?> returnedObjectType = getReturnedObjectType();
        Class<?> domainClass = getDomainClass();

        MongoPersistentEntity<?> returnedEntity = mappingContext.getPersistentEntity(getReturnedObjectType());
        MongoPersistentEntity<?> managedEntity = mappingContext.getPersistentEntity(domainClass);
        returnedEntity = returnedEntity == null ? managedEntity : returnedEntity;
        MongoPersistentEntity<?> collectionEntity = domainClass.isAssignableFrom(returnedObjectType) ? returnedEntity
                : managedEntity;

        this.metadata = new SimpleMongoEntityMetadata<Object>((Class<Object>) returnedEntity.getType(),
                collectionEntity.getCollection());
    }

    return this.metadata;
}

我想要什么

即使是@Query带注释的存储库方法,如何在运行时选择集合名称?

由于

1 个答案:

答案 0 :(得分:1)

看起来您正在运行into this问题,该问题最近已修复,刚刚在Spring Data MongoDB 1.7 M1中发布,并计划在即将发布的1.6.2和1.5.5版本中发布。随意给里程碑一个旋转。