enititymanager persistenceprovider, EM-Factory
This commit is contained in:
5
pom.xml
5
pom.xml
@@ -134,6 +134,11 @@
|
|||||||
<artifactId>spring-jdbc</artifactId>
|
<artifactId>spring-jdbc</artifactId>
|
||||||
<version>${spring.version}</version>
|
<version>${spring.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-orm</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-tx</artifactId>
|
<artifactId>spring-tx</artifactId>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.springframework.persistence.graph.neo4j;
|
|||||||
|
|
||||||
import org.neo4j.graphdb.GraphDatabaseService;
|
import org.neo4j.graphdb.GraphDatabaseService;
|
||||||
import org.neo4j.graphdb.Node;
|
import org.neo4j.graphdb.Node;
|
||||||
|
import org.neo4j.graphdb.Relationship;
|
||||||
import org.neo4j.kernel.EmbeddedGraphDatabase;
|
import org.neo4j.kernel.EmbeddedGraphDatabase;
|
||||||
import org.springframework.persistence.support.EntityInstantiator;
|
import org.springframework.persistence.support.EntityInstantiator;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -15,7 +16,7 @@ import javax.transaction.*;
|
|||||||
* @since 20.08.2010
|
* @since 20.08.2010
|
||||||
* TODO Relationships
|
* TODO Relationships
|
||||||
*/
|
*/
|
||||||
@Service
|
//@Service
|
||||||
public class Neo4jEntityManager implements EntityManager {
|
public class Neo4jEntityManager implements EntityManager {
|
||||||
@Resource
|
@Resource
|
||||||
GraphDatabaseService graphDatabaseService;
|
GraphDatabaseService graphDatabaseService;
|
||||||
@@ -24,7 +25,15 @@ public class Neo4jEntityManager implements EntityManager {
|
|||||||
EntityInstantiator<NodeBacked, Node> nodeInstantiator;
|
EntityInstantiator<NodeBacked, Node> nodeInstantiator;
|
||||||
private volatile boolean closed;
|
private volatile boolean closed;
|
||||||
|
|
||||||
private Node nodeFor(Object entity) {
|
public Neo4jEntityManager(final GraphDatabaseService graphDatabaseService, final EntityInstantiator<NodeBacked, Node> nodeInstantiator) {
|
||||||
|
this.graphDatabaseService = graphDatabaseService;
|
||||||
|
this.nodeInstantiator = nodeInstantiator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Neo4jEntityManager() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node nodeFor(final Object entity) {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
if (!(entity instanceof NodeBacked)) throw new IllegalArgumentException("Not a nodebacked entity " + entity);
|
if (!(entity instanceof NodeBacked)) throw new IllegalArgumentException("Not a nodebacked entity " + entity);
|
||||||
final Node node = ((NodeBacked) entity).getUnderlyingNode();
|
final Node node = ((NodeBacked) entity).getUnderlyingNode();
|
||||||
@@ -45,7 +54,11 @@ public class Neo4jEntityManager implements EntityManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(final Object entity) {
|
public void remove(final Object entity) {
|
||||||
nodeFor(entity).delete();
|
final Node node = nodeFor(entity);
|
||||||
|
for (final Relationship r : node.getRelationships()) {
|
||||||
|
r.delete();
|
||||||
|
}
|
||||||
|
node.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package org.springframework.persistence.graph.neo4j;
|
||||||
|
|
||||||
|
import org.neo4j.graphdb.GraphDatabaseService;
|
||||||
|
import org.neo4j.graphdb.Node;
|
||||||
|
import org.springframework.beans.factory.annotation.Configurable;
|
||||||
|
import org.springframework.persistence.support.EntityInstantiator;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Michael Hunger
|
||||||
|
* @since 23.08.2010
|
||||||
|
*/
|
||||||
|
public class Neo4jEntityManagerFactory implements EntityManagerFactory {
|
||||||
|
@Resource
|
||||||
|
GraphDatabaseService graphDatabaseService;
|
||||||
|
@Resource
|
||||||
|
EntityInstantiator<NodeBacked, Node> nodeInstantiator;
|
||||||
|
|
||||||
|
public Neo4jEntityManagerFactory() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Neo4jEntityManagerFactory(GraphDatabaseService graphDatabaseService, EntityInstantiator<NodeBacked, Node> nodeInstantiator) {
|
||||||
|
this.graphDatabaseService = graphDatabaseService;
|
||||||
|
this.nodeInstantiator = nodeInstantiator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityManager createEntityManager() {
|
||||||
|
return new Neo4jEntityManager(graphDatabaseService,nodeInstantiator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO handle different directories for target datastore */
|
||||||
|
@Override
|
||||||
|
public EntityManager createEntityManager(Map map) {
|
||||||
|
return new Neo4jEntityManager(graphDatabaseService,nodeInstantiator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpen() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package org.springframework.persistence.graph.neo4j;
|
||||||
|
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.jdbc.datasource.ConnectionHandle;
|
||||||
|
import org.springframework.orm.jpa.EntityManagerFactoryPlusOperations;
|
||||||
|
import org.springframework.orm.jpa.EntityManagerPlusOperations;
|
||||||
|
import org.springframework.orm.jpa.JpaDialect;
|
||||||
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
|
import org.springframework.transaction.TransactionException;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Michael Hunger
|
||||||
|
* @since 23.08.2010
|
||||||
|
*/
|
||||||
|
public class Neo4jJpaDialect implements JpaDialect {
|
||||||
|
@Override
|
||||||
|
public boolean supportsEntityManagerFactoryPlusOperations() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsEntityManagerPlusOperations() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityManagerFactoryPlusOperations getEntityManagerFactoryPlusOperations(final EntityManagerFactory entityManagerFactory) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityManagerPlusOperations getEntityManagerPlusOperations(final EntityManager entityManager) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo
|
||||||
|
@Override
|
||||||
|
public Object beginTransaction(final EntityManager entityManager, final TransactionDefinition transactionDefinition) throws PersistenceException, SQLException, TransactionException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object prepareTransaction(final EntityManager entityManager, final boolean b, final String s) throws PersistenceException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanupTransaction(final Object o) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConnectionHandle getJdbcConnection(final EntityManager entityManager, final boolean b) throws PersistenceException, SQLException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void releaseJdbcConnection(final ConnectionHandle connectionHandle, final EntityManager entityManager) throws PersistenceException, SQLException {
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo
|
||||||
|
@Override
|
||||||
|
public DataAccessException translateExceptionIfPossible(final RuntimeException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,9 +62,6 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<Graph.E
|
|||||||
pointcut arbitraryUserConstructorOfNodeBackedObject(NodeBacked entity) :
|
pointcut arbitraryUserConstructorOfNodeBackedObject(NodeBacked entity) :
|
||||||
execution((@Graph.Entity *).new(..)) &&
|
execution((@Graph.Entity *).new(..)) &&
|
||||||
!execution((@Graph.Entity *).new(Node)) &&
|
!execution((@Graph.Entity *).new(Node)) &&
|
||||||
this(entity);
|
|
||||||
execution((@GraphEntity *).new(..)) &&
|
|
||||||
!execution((@GraphEntity *).new(Node)) &&
|
|
||||||
this(entity); // && !cflow(execution(* fromStateInternal(..));
|
this(entity); // && !cflow(execution(* fromStateInternal(..));
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package org.springframework.persistence.graph.neo4j;
|
||||||
|
|
||||||
|
import org.neo4j.graphdb.GraphDatabaseService;
|
||||||
|
import org.neo4j.graphdb.Node;
|
||||||
|
import org.springframework.persistence.support.EntityInstantiator;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.spi.PersistenceProvider;
|
||||||
|
import javax.persistence.spi.PersistenceUnitInfo;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Michael Hunger
|
||||||
|
* @since 23.08.2010
|
||||||
|
*/
|
||||||
|
// todo handle additinal info + database path
|
||||||
|
public class Neo4jPersistenceProvider implements PersistenceProvider {
|
||||||
|
@Resource
|
||||||
|
GraphDatabaseService graphDatabaseService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
EntityInstantiator<NodeBacked, Node> nodeInstantiator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityManagerFactory createEntityManagerFactory(String emName, Map map) {
|
||||||
|
return new Neo4jEntityManagerFactory(graphDatabaseService,nodeInstantiator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) {
|
||||||
|
return new Neo4jEntityManagerFactory(graphDatabaseService,nodeInstantiator);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package org.springframework.persistence.graph.neo4j;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityTransaction;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.neo4j.graphdb.GraphDatabaseService;
|
||||||
|
import org.neo4j.graphdb.Node;
|
||||||
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
|
import org.springframework.persistence.test.Person;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Michael Hunger
|
||||||
|
* @since 20.08.2010
|
||||||
|
*/
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(locations = {"classpath:org/springframework/persistence/test/graph/Neo4jGraphPersistenceTest-context.xml"})
|
||||||
|
@Transactional
|
||||||
|
public class Neo4jEntityManagerTest {
|
||||||
|
@Resource
|
||||||
|
GraphDatabaseService graphDatabaseService;
|
||||||
|
@PersistenceContext(unitName="neo4j-persistence")
|
||||||
|
EntityManager entityManager;
|
||||||
|
|
||||||
|
Person person;
|
||||||
|
private Node node;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void cleanDb() {
|
||||||
|
Neo4jHelper.cleanDb(graphDatabaseService);
|
||||||
|
node = graphDatabaseService.createNode();
|
||||||
|
person = new Person(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPersist() throws Exception {
|
||||||
|
entityManager.persist(person);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMerge() throws Exception {
|
||||||
|
Person merged=entityManager.merge(person);
|
||||||
|
assertEquals(person,merged);
|
||||||
|
}
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void testRemove() throws Exception {
|
||||||
|
long nodeId=node.getId();
|
||||||
|
entityManager.remove(person);
|
||||||
|
final Node foundNode = graphDatabaseService.getNodeById(nodeId);
|
||||||
|
assertNull(foundNode);
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void testFind() throws Exception {
|
||||||
|
final Person found = entityManager.find(Person.class, node.getId());
|
||||||
|
assertEquals(person,found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetReference() throws Exception {
|
||||||
|
final Person found = entityManager.getReference(Person.class, node.getId());
|
||||||
|
assertEquals(person,found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFlush() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetFlushMode() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetFlushMode() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLock() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRefresh() throws Exception {
|
||||||
|
entityManager.refresh(person);
|
||||||
|
assertEquals(node, person.getUnderlyingNode());
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void testClear() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=InvalidDataAccessApiUsageException.class)
|
||||||
|
public void removeThrowsErrorForNonNodeBacked() throws Exception {
|
||||||
|
entityManager.remove(new Object());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContains() throws Exception {
|
||||||
|
final Person p2 = new Person("Rod",39);
|
||||||
|
assertTrue(entityManager.contains(person));
|
||||||
|
assertTrue(entityManager.contains(p2));
|
||||||
|
assertFalse(entityManager.contains(new Object()));
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
@Test
|
||||||
|
public void testCreateQuery() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateNamedQuery() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateNativeQuery() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJoinTransaction() throws Exception {
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetDelegate() throws Exception {
|
||||||
|
assertTrue(entityManager.getDelegate() instanceof GraphDatabaseService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=InvalidDataAccessApiUsageException.class)
|
||||||
|
public void testClose() throws Exception {
|
||||||
|
entityManager.close();
|
||||||
|
assertFalse(entityManager.isOpen());
|
||||||
|
entityManager.refresh(person);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsOpen() throws Exception {
|
||||||
|
assertTrue(entityManager.isOpen());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetTransaction() throws Exception {
|
||||||
|
final EntityTransaction transaction = entityManager.getTransaction();
|
||||||
|
assertFalse(transaction.getRollbackOnly());
|
||||||
|
person.setName("Michael");
|
||||||
|
entityManager.persist(person);
|
||||||
|
transaction.setRollbackOnly();
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/test/resources/META-INF/persistence.xml
Normal file
10
src/test/resources/META-INF/persistence.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
|
||||||
|
|
||||||
|
<persistence-unit name="neo4j-persistence" transaction-type="RESOURCE_LOCAL">
|
||||||
|
<provider>org.springframework.persistence.graph.neo4j.Neo4jPersistenceProvider</provider>
|
||||||
|
<properties>
|
||||||
|
<property name="neo4j.path" value="test/data"/> <!-- TODO handle this -->
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
</persistence>
|
||||||
@@ -125,5 +125,15 @@
|
|||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
|
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
|
||||||
|
|
||||||
|
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
|
||||||
|
<property name="jpaDialect">
|
||||||
|
<bean class="org.springframework.persistence.graph.neo4j.Neo4jJpaDialect"/>
|
||||||
|
</property>
|
||||||
|
<property name="persistenceProvider">
|
||||||
|
<bean class="org.springframework.persistence.graph.neo4j.Neo4jPersistenceProvider"/>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!--bean id="neoEntityManager" class="org.springframework.persistence.graph.neo4j.Neo4jEntityManager" scope="prototype"/-->
|
||||||
</beans>
|
</beans>
|
||||||
|
|||||||
Reference in New Issue
Block a user