使用Spring-Data-Neo4j的@Transactional头痛

时间:2014-07-22 04:33:25

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

我对spring-data-neo4j还是比较新的,虽然我很乐意在大多数情况下与它进行交互,但我在事务管理中遇到了一些周期性重复出现的问题(使用简单的映射),我不明白,这是非常令人沮丧的。

控制器:

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserService userService;


    @RequestMapping("/{id}/posts")
    @ResponseBody
    public Set<POSTED> getPosts(@PathVariable Long id){
        //POSTED is a @RelationshipEntity-annotated class
        return userService.getItemsPosted(id);
    }
    //...
}

服务界面:

public interface UserService extends DomainService<User> {

    User load(long id);   //works fine
    User createNew(Map<String, Object> props);   //works fine
    Set<POSTED> getItemsPosted(User u);   //NotInTransactionException !!! 

}

服务实施:

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired UserRepo repo; //standard empty interface extending GraphRepository<User>
    @Autowired Neo4jTemplate template;

    @Override
    @Transactional
    public User load(long id) {
        return repo.findOne(id); 
    }

    @Override
    @Transactional
    public Set<User> loadAll(int howMany) {
        Result<User> result = repo.findAll();
        Iterator<User> iter = result.iterator();

        if (!iter.hasNext()) throw new RuntimeException(" the result is empty!");
        User next =iter.next();

        HashSet<User> toret = new HashSet<User>();
        for (int i =0; i < howMany && iter.hasNext(); i++, next = iter.next() ) {
            toret.add(next); 
        }
    return toret;
    }

    @Override
    @Transactional
    public void save(User u) {
        template.save(u);
    }

    @Override
    @Transactional
    public User createNew(Map<String, Object> props) {
        return repo.save(new User(props));
    }

    @Override
    @Transactional
    public Set<POSTED> getItemsPosted(User u) {
        return template.fetch(u.posts); //NotInTransactionException 
    }
}

域名实体

@NodeEntity
@TypeAlias("user")
public class User implements DomainNode {
    @GraphId
    Long id;
    //...
    @RelatedToVia
    Set<POSTED> posts = new HashSet<>();
    //...
 }

如上所述,导致问题的唯一调用是getItemsPosted() - 这恰好是直接调用Neo4jTemplate的唯一方法:其他方法,也可以通过调用GraphRepository来执行交易,并且工作正常。

我可以理解为@Transactional根本不适用于Neo4jTemplate上的通话吗?我知道我可以通过使用template.getGraphDatabase().beginTx()手动启动交易来解决异常 - 我的问题是,是否有更好的方法来处理这样的情况。我有这种潜伏的感觉,我在这里以某种方式反对这个框架,这使我的生活变得比以前更难。

0 个答案:

没有答案