【问题标题】:Spring Data / Neo4J Repository : findByXXX returns Map, not EntitySpring Data / Neo4J Repository:findByXXX 返回 Map,而不是 Entity
【发布时间】:2013-07-19 03:02:30
【问题描述】:

我正在使用 Spring Data Neo4J。

我已经扩展了基本的GraphRepository接口,添加了一个方法,如下:

/**
 * Extension to the repository interface for standard Spring Data repo's that
 * perform operations on graph entities that have a related RDBMS entity.
 * 
 * @author martypitt
 *
 * @param <T>
 */
public interface RelatedEntityRepository<T> extends GraphRepository<T>, 
RelationshipOperationsRepository<T>,CypherDslRepository<T>  {
    public T findByEntityId(Long id);
}

但是,我发现此接口的子类的行为与预期不符。

public interface UserRepository extends RelatedEntityRepository<UserNode>{
}

当我调用UserRepository.findByEntityId(1L) 时,我希望得到UserNode 的单个实例返回,或null

相反,我收到了scala.collection.JavaConversions$MapWrapper

但是,如果我更改 UserRepository 以指定类型,那么一切正常(虽然,违背了基类的目的)

public interface UserRepository extends RelatedEntityRepository<UserNode>{
    public UserNode findByEntityId(Long id);
}

这是一个测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"/graph-test-context.xml"})
@Transactional
public class UserRepositoryTests {

    @Autowired
    private UserRepository userRepository;

    // For Bug
    @Test
    public void canFindByEntityId()
    {
        UserNode userNode = new UserNode(1L);
        userRepository.save(userNode);

        UserNode node = userRepository.findByEntityId(1L);
        assertThat(node, notNullValue());
        assertThat(node, isA(UserNode.class));
    }
}

使用注释掉 UserRepository 中的额外行运行此测试失败。否则,测试通过。

这是一个错误吗?我的repo接口写对了吗?

【问题讨论】:

  • 似乎存储库方法正在返回一个 Result 对象而不是正确的类对象。您可以尝试将 findByEntityId 方法返回的对象转换为 Neo4jOperations 类的 convert 方法:UserNode node = neo4jOperations.convert(userRepository.findByEntityId(1L), UserNode.class);

标签: java spring-data spring-data-neo4j


【解决方案1】:

remigio 是对的,它返回一个你必须转换的包装对象。

但是,对于不同的实体类型使用公共基类是不可能的。

原因如下:

您认为为带有@MapResult 注释的查询结果创建一个包装类应该可以,例如。

@MapResult
public interface ResultMap<T> {
    @ResultColumn("usernode") <T> getNode();
}

并在您的存储库类中像这样使用它:

ResultMap<T> findByEntityId(Long id);

在你的测试中像这样:

ReultMap<UserNode> = userRepository.findByEntityId(1L);

很遗憾,这不起作用,原因有两个:

  • 存储库在映射中返回 NodeProxy 类而不是 UserNode
  • @ResultColumn 注释必须配置一个列名,这似乎是根据类的类型在结果中自动生成的,在你的例子中是“usernode”。

然后是这样的:

@MapResult
public interface ResultMap {
    @ResultColumn("usernode") NodeProxy getNode();
}

ResultMap rm = userRepository.findByEntityId(1L);
NodeProxy proxy = rm.getNode();
UserNode userNode = template.convert(proxy, UserNode.class);

template 是这样自动连线的:

@Autowired Neo4jOperations template;

不幸的是,由于上面的第 2 点,这也不起作用:(

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-19
    • 2018-08-08
    • 2018-01-17
    • 2016-04-19
    • 2015-09-09
    • 2017-06-12
    相关资源
    最近更新 更多