2014-01-13 4 views
0

Я перенесил свои бобы в CDI, и у меня возникло странное поведение Neo4j, где он не сохраняется на узлах (но правильно завершает транзакцию) без указания какой-либо ошибки ,Neo4J CDI тихий сбой при изменении @ApplicationScoped в @SessionScoped

Что еще более затрудняет то, что тот же призыв к добавлению узла работает при вызове внутри postCosntructor, но не при вызове из службы REST! (Г() вызывается из другого класса RestService не показан)

@Named 
@SessionScoped 
public class MyNeo4JController implements Serializable 
{ 
    @Inject 
    private Neo4JGraph neo4jGraph; 
    public MyNeo4JController() 
    { 
    if (neo4jGraph == null) 
     { 
      neo4jGraph = new Neo4JGraph(); 
     } 
    } 

    @PostConstruct 
    void postConstruct() 
    { 
     f(); 
    } 

    public void f() 
    { 
    getGraphStorage().addNode("F"); 
    } 

    public void g() 
    { 
    getGraphStorage().addNode("G"); 
    } 
} 

@Singleton 
public class Neo4JGraph 
{ 
    private static final String FILESYSTEM_DB = "target/neo4j-db"; 
    private GraphDatabaseService graphDb; 
    public void addNode(String name) 
    { 
     Transaction tx = graphDb.beginTx(); 
     try 
     { 
      Node newNode = graphDb.createNode(); 
      newNode.setProperty("name", name); 
      tx.success(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
      tx.failure(); 
     } 
     finally 
     { 
      tx.finish(); 
     } 
     return true; 
    } 

    public void setUp(String rootUuid) 
    { 
     if (graphDb == null) 
     { 
      graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(FILESYSTEM_DB); 
      indexManager = graphDb.index(); 
      index = indexManager.forNodes("indexNodes"); 
      registerShutdownHook(); 
      setGraphRootUUIDString(rootUuid); 
     } 
    } 
} 

Есть некоторые тайные Несовместимость КДИ и Neo4j или я чего-то не хватает?

EDIT: ОК, очевидно, я сузил ошибку, изменив @SessionScoped в MyNeo4JController на @ApplicationScoped, и теперь узлы сохраняются. Обратите внимание, что в обоих случаях ошибка не была возвращена, но с SessionScoped ни один узел не был добавлен!

У кого-нибудь есть идея, почему? потому что я не могу сохранить этот класс как ApplicationScoped!

ответ

0

Извлечение конструктора из компонента SessionScoped решит проблему. С существующим кодом вы создаете новую базу данных каждый раз, когда создается новый сеанс.

+0

Я фактически создаю новый объект базы данных, используя ту же базу данных с FILESYSTEM_DB = "target/neo4j-db"; Если я удалю конструктор из компонента, как инициализируется база данных? – dendini

+0

Экземпляр GraphDataBaseService - это сам экземпляр сервера базы данных, а не только сеанс или соединение. Если вы используете его встроенным способом (как и вы), вам нужно оставить его как одноэлемент в своем приложении и обеспечить надлежащее завершение работы при остановленном приложении - лучше всего создать экземпляр GraphDataBaseService в методе PostConstruct и закрыть его вниз в методе PreDestroy компонента ApplicationScoped и просто возвращать экземпляр другим бобам (RequestScoped, SessionScoped и т. д.) без дополнительной магии. Им нужна надлежащая реализация транзакций. –

Смежные вопросы