enititymanager persistenceprovider, EM-Factory
This commit is contained in:
5
pom.xml
5
pom.xml
@@ -134,6 +134,11 @@
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.springframework.persistence.graph.neo4j;
|
||||
|
||||
import org.neo4j.graphdb.GraphDatabaseService;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.neo4j.kernel.EmbeddedGraphDatabase;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -15,7 +16,7 @@ import javax.transaction.*;
|
||||
* @since 20.08.2010
|
||||
* TODO Relationships
|
||||
*/
|
||||
@Service
|
||||
//@Service
|
||||
public class Neo4jEntityManager implements EntityManager {
|
||||
@Resource
|
||||
GraphDatabaseService graphDatabaseService;
|
||||
@@ -24,7 +25,15 @@ public class Neo4jEntityManager implements EntityManager {
|
||||
EntityInstantiator<NodeBacked, Node> nodeInstantiator;
|
||||
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();
|
||||
if (!(entity instanceof NodeBacked)) throw new IllegalArgumentException("Not a nodebacked entity " + entity);
|
||||
final Node node = ((NodeBacked) entity).getUnderlyingNode();
|
||||
@@ -45,7 +54,11 @@ public class Neo4jEntityManager implements EntityManager {
|
||||
|
||||
@Override
|
||||
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"})
|
||||
|
||||
@@ -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) :
|
||||
execution((@Graph.Entity *).new(..)) &&
|
||||
!execution((@Graph.Entity *).new(Node)) &&
|
||||
this(entity);
|
||||
execution((@GraphEntity *).new(..)) &&
|
||||
!execution((@GraphEntity *).new(Node)) &&
|
||||
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>
|
||||
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user