Java @Spring-Data-Neo4j的事务性难题
我对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") @
@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
的唯一方法:其他方法也执行事务,通过调用myGraphRespository
来执行,并且工作正常
我是否可以认为这意味着
@Transactional
不适用于在Neo4jTemplate
上进行的调用?我知道我可以通过使用template.getGraphDatabase().beginTx()
-手动启动一个事务来绕过异常。我的问题是,是否有更好的方法来处理这种情况。我有一种潜在的感觉,我正在以某种方式与框架对抗,这让我的生活比它需要的更艰难。你能发布完整的stacktrace吗?另外,在创建模板和tx管理器的地方发布代码或xml配置。我希望它会在u.posts
调用中出现,而不是在template.fetch
调用中出现。请发布完整的stacktrace以了解更多信息。