OK Solution inspired from here https://github.com/mstahv/bootiful-neo4j-with-vaadin/blob/master/src/main/java/org/vaadin/neo4j/AppService.java. He is implementing a @Service annotated with @Transactional before using the repository in the controller.
NullPointerException TopLevelTransaction.markAsRollbackOnly Neo4J-Boot for findAll() method
-
16-07-2023 - |
Pergunta
I am trying to follow Josh Long - Philip Sorst example in order to perform Angular SPA-Rest Authentication and CRUD actions using Neo4J as db (excellent work. Thanks a lot guys). But I am stuck at a very early stage and I suspect it's not my fault. Please help Neo4J-Angular-Spring lovers. My code can be found here and it is very easy to run just clone and give mvn spring-boot:run
Now the problem is that I get the following exception only for the findAll() method of the GraphRepository.
Caused by: java.lang.NullPointerException: null
at org.neo4j.kernel.TopLevelTransaction.markAsRollbackOnly(TopLevelTransaction.java:93)
... 88 common frames omitted
and I will replicate some of my code:
Neo4JConfig.java
@Configuration
@EnableNeo4jRepositories(basePackages = "demo.repository.neo4j")
public class Neo4JConfig extends Neo4jConfiguration {
public Neo4JConfig() {
setBasePackage("demo.model.neo4j");
}
@Bean(destroyMethod = "shutdown")
public GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabase("data/demo.db");
}
@Bean
public Neo4jTemplate neo4jTemplate() {
return new Neo4jTemplate(graphDatabaseService());
}
}
NewsEntry.java
@NodeEntity
public class NewsEntry {
@GraphId
private Long id;
private String content;
public NewsEntry() {}
public NewsEntry(String b) {
this.content = b;
}
public Long getId() {
return this.id;
}
public String getContent() {
return this.content;
}
public void setId(Long id) {
this.id = id;
}
public void setContent(String content) {
this.content = content;
}
}
NewsEntryRepository.java
public interface NewsEntryRepository extends GraphRepository<NewsEntry> {
}
NewsEntryController.java
@RestController
class NewsController {
@Autowired
private NewsEntryRepository newsEntryRepository;
@RequestMapping("/news")
List<NewsEntry> entries() {
List<NewsEntry> list = new ArrayList<NewsEntry>();
Iterable<NewsEntry> results = newsEntryRepository.findAll();
for (NewsEntry r : results) {
list.add(r);
}
return list;
}
@RequestMapping(value = "/news/{id}", method = RequestMethod.DELETE)
void remove(@PathVariable Long id) {
this.newsEntryRepository.delete(id);
return;
}
@RequestMapping(value = "/news/{id}", method = RequestMethod.GET)
NewsEntry entry(@PathVariable Long id) {
return this.newsEntryRepository.findOne(id);
}
@RequestMapping(value = "/news/{id}", method = RequestMethod.POST)
NewsEntry update(@PathVariable Long id, @RequestBody NewsEntry news) {
NewsEntry old = this.newsEntryRepository.findOne(id);
old = news;
return this.newsEntryRepository.save(old);
}
@RequestMapping(value = "/news", method = RequestMethod.POST)
NewsEntry add(@RequestBody NewsEntry news) {
this.newsEntryRepository.save(new NewsEntry(news.getContent()));
return news;
}
}
Solução
Outras dicas
You shouldn't have to override:
@Bean
public Neo4jTemplate neo4jTemplate() {
return new Neo4jTemplate(graphDatabaseService());
}
And can you try to add the annotation:
@EnableTransactionManagement
to your config?
Something is telling me that the solution is hiding somewhere here. I will give it a go and let you know.
OK This works only if you change the version of Spring-data-neo4j to 2.3.3.RELEASE. If you use the latest version you get the same problem as above. I think I should open an issue.
But that's not the solution as I would like to use Neo4J Server Community 2.0.3 to open the graph for visualization afterwards. Also I do not understand this solution beanfactories, injects instead of autowired???. However I will make another branch for this solution in my github repo.