Java @Spring-Data-Neo4j的事务性难题

Java @Spring-Data-Neo4j的事务性难题,java,spring,spring-data,spring-data-neo4j,Java,Spring,Spring Data,Spring Data Neo4j,我对spring-data-neo4j还比较陌生,虽然我在很大程度上喜欢与它进行交互,但在事务管理(使用简单映射)方面,我遇到了一些周期性的问题,这些问题我不理解,而且非常令人沮丧 控制器: @Controller @RequestMapping("/user") public class UserController { @Autowired UserService userService; @RequestMapping("/{id}/posts") @

我对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 
    }
}
@控制器
@请求映射(“/user”)
公共类用户控制器{
@自动连线
用户服务用户服务;
@请求映射(“/{id}/posts”)
@应答器
公共设置getPosts(@PathVariable Long id){
//POSTED是一个@RelationshipEntity注释类
返回userService.getItemsPosted(id);
}
//...
}
服务接口:

@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 
    }
}
公共接口用户服务扩展域服务{
用户加载(长id);//工作正常
用户createNew(地图道具);//工作正常
设置getItemsPosted(用户u);//NotInTransactionException!!!
}
服务实施:

@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 
    }
}
@服务
@交易的
公共类UserServiceImpl实现UserService{
@Autowired UserRepo repo;//扩展GraphRespository的标准空接口
@自动连线Neo4jTemplate模板;
@凌驾
@交易的
公共用户负载(长id){
返回已完成的回购(id);
}
@凌驾
@交易的
公共集loadAll(整数多少){
结果=repo.findAll();
迭代器iter=result.Iterator();
如果(!iter.hasNext())抛出新的RuntimeException(“结果为空!”);
User next=iter.next();
HashSet toret=新的HashSet();
对于(int i=0;i
域实体

@NodeEntity
@TypeAlias("user")
public class User implements DomainNode {
    @GraphId
    Long id;
    //...
    @RelatedToVia
    Set<POSTED> posts = new HashSet<>();
    //...
 }
@NodeEntity
@TypeAlias(“用户”)
公共类用户实现DomainNode{
@格拉希德
长id;
//...
@相关的
Set posts=newhashset();
//...
}
如上所述,导致问题的唯一调用是
getItemsPosted()
——这恰好是直接调用
Neo4jTemplate
的唯一方法:其他方法也执行事务,通过调用my
GraphRespository
来执行,并且工作正常


我是否可以认为这意味着
@Transactional
不适用于在
Neo4jTemplate
上进行的调用?我知道我可以通过使用
template.getGraphDatabase().beginTx()
-手动启动一个事务来绕过异常。我的问题是,是否有更好的方法来处理这种情况。我有一种潜在的感觉,我正在以某种方式与框架对抗,这让我的生活比它需要的更艰难。

你能发布完整的stacktrace吗?另外,在创建模板和tx管理器的地方发布代码或xml配置。我希望它会在
u.posts
调用中出现,而不是在
template.fetch
调用中出现。请发布完整的stacktrace以了解更多信息。