考虑一个简单的域类: -
@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带注释的存储库方法,如何在运行时选择集合名称?
由于
答案 0 :(得分:1)
看起来您正在运行into this问题,该问题最近已修复,刚刚在Spring Data MongoDB 1.7 M1中发布,并计划在即将发布的1.6.2和1.5.5版本中发布。随意给里程碑一个旋转。