datanucleus / datanucleus-neo4j Goto Github PK
View Code? Open in Web Editor NEWDataNucleus support for persistence to Neo4j Datastores
DataNucleus support for persistence to Neo4j Datastores
If we have a JDOQL query of
this.prop = null
this should become
this.prop IS NULL
Similarly if we have
this.prop != null
this should become
this.prop IS NOT NULL
When a relation is updated from one side we need to make sure that the other side is kept consistent (so that the L2 cache is updated accordingly), otherwise tests can fail due to the other side thinking that a field has a particular value when, in fact, it was removed.
Map on to Neo4j associated functions.
We currently support no method invocations in Neo4j queries. Add these so we provide a framework for others to follow for further method support
Hi!
A new Object is created whenever I try to set it to an object property. Let someone reproduce this. Is it the default behavior?
public class ProductClass implements Serializable {
...
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
long id;
@Persistent
private String name = null;
...
}
public class Product implements Serializable {
...
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
long id;
@Persistent
private String name = null;
@Persistent(defaultFetchGroup = "true")
private ProductClass productClass = null;
...
}
Persisting the Product like this;
Product prod = new Product();
prod.setName('productName');
prod.setProductClass(prodClass);
PersistenceManager pm = JDOUtil.PERSISTENCE_MANAGER_FACTORY.getPersistenceManager();
Transaction tx = pm.currentTransaction();
try {
tx.begin();
pm.makePersistent(prod);
Object id = pm.getObjectId(prod);
tx.commit();
} finally {
if (tx.isActive()) {
tx.rollback();
}
pm.close();
}
Instead of setting the ProductClass to the Product, new ProductClass is produced.
If we have an M-N relation and we want to store some properties on the relation we create an intermediate model class, with the source and target objects present as well as the properties we want to store. Currently this will be stored as a Node, with Relationship to source Node, and Relationship to target Node. Would be a nice alternative to be able to persist objects of this type as a Relationship between Node for source and Node for target.
Would only apply to POJO that has 2 relation fields (source and target, and no other), and these objects cannot be null. The majority of SVN trunk already uses PropertyContainer instead of Node, and Neo4jUtils has a convenience method to detect if a class is marked as "attributed relation".
We currently support embedded Neo4j. Neo4j v3.0.0 will feature a BOLT protocol that allows connection to remote instances via the normal driver. See
https://github.com/neo4j/neo4j-java-driver
https://neo4j.com/blog/neo4j-3-0-milestone-1-release/
Hi.
I tried to execute a code like this, and I got a stack trace.
JDOPersistenceManager jdopm = (JDOPersistenceManager) pm;
QProductClass cand = QProductClass.candidate();
JDOQLTypedQuery<Product> tq = jdopm.newJDOQLTypedQuery(Product.class);
List<Product> prods = tq.filter(cand.name.ne(value)).executeList();
The stacktrace;
Jan 03, 2018 8:01:14 PM com.hop.tub.servlets.TuListDataServlet doPost
SEVERE: null
org.neo4j.graphdb.QueryExecutionException: Unknown operation '!=' (you probably meant to use '<>', which is the operator for inequality testing) (line 1, column 95 (offset: 94))
"START this=node:DN_TYPES(class="com.hop.tub.neo4j.jdo.model.Product") WHERE (this.name != "ampiclox") RETURN this"
^
at org.neo4j.kernel.impl.query.QueryExecutionKernelException.asUserException(QueryExecutionKernelException.java:35)
3at org.neo4j.kernel.impl.factory.ClassicCoreSPI.executeQuery(ClassicCoreSPI.java:84)
at org.neo4j.kernel.impl.factory.GraphDatabaseFacade.execute(GraphDatabaseFacade.java:369)
at org.neo4j.kernel.impl.factory.GraphDatabaseFacade.execute(GraphDatabaseFacade.java:359)
at org.datanucleus.store.neo4j.Neo4jUtils.executeCypherQuery(Neo4jUtils.java:319)
I am able to use equality and starts-with methods .eq()
and .startsWith()
respectively, but .ne()
gives Exception.
I think this line explains the problem with the plugin.
org.neo4j.graphdb.QueryExecutionException: Unknown operation '!=' (you probably meant to use '<>', which is the operator for inequality testing) (line 1, column 95 (offset: 94))
When we create a Node we currently put it into the index for the class in question, as
db.index().forNodes("DN_TYPES").add(node, "class", className);
If the table name is specified we likely should do
db.index().forNodes("DN_TYPES").add(node, "class", tableName);
Note that, to find the object in a polymorphic query, if the class has persistable superclasses then we also put it with that class too, so would need to use the table name of the superclass in that case also
The closed bug #27, is actually caused by the @Persistent annotation having defaultFetchGroup property set to "true".
see test "RelatedObjectNotPersisted" in https://github.com/dhakehurst/test-jdo
See PersistenceNucleusContext.
Refer to datanucleus/datanucleus-core#135
But what Java calls are needed to achieve this? The Neo4j "manual" isn't a "good read" for such things. If anyone knows then please contribute such information
Current SVN trunk will persist any null field by just omitting the property. This matches Neo4j advice about how to handle null property values.
This will obviously cause problems with any query that makes explicit mention of the field, and will get an exception about Node xxx not having the property. We should update any query that is comparing against a particular value to check if the property exists and if comparing with null to check if it doesn't exist.
It may work out of the box, but need to build/test against it
the latest release of neo4j is 3.1.3.
if I use the datanucleus conector in my code, I cannot use the neo4j tools to view the same data, because datanucleus-neo4j uses an older (incompatible) version of the libraries.
If we have
Sample2
{
Sample3 sample3;
}
Sample3
{
Sample3 sample3;
}
and we have a Sample2 related to a Sample3. When retrieving the Sample3 field "sample3" it will find the Relationship to the Sample2 (since the field name is the same). Currently we do no check on which Node owns the relation (just the field name). Need to add a check on the startNode.
Hi!
I have already asked this question on StackOverflow here. I think it will be beneficial to support missing (non-String) columns in Neo4j database. Because of this lack I have to discard the whole database whenever I want to add new non-String column to my model.
Neo4j "count" queries are totally illogical. If you have no Node(s) for the cypher query and do something like
START T=node:DN_TYPES(class="org.jpox.samples.annotations.models.company.Person") RETURN count(T)
then this just returns an empty result set (iter.hasNext() == false). Need to cater for this nonsense.
version: 5.1.0-m1
test case: https://github.com/dhakehurst/test-jdo, SimpleTest.CompoundIdentity()
Error from stacktrace indicates a badly formed CYPHER statement
"START pc=node:DN_TYPES(class="mydomain.model.CompoundItem") WHERE (pc.id = "item1" and pc.owner = cont1) RETURN pc"
maybe missing quotes around the "cont1".
I think that the problem might be the if statement at line 193 of Neo4jUtils.
it tests if the storedValue is an instance of a String, and inserts quotes if so, else no quotes.
However, in the case of the compound PK, the PK is stored as a String (I think).
So an additional test to catch the PK case needs to be added.
Am not sure how to test for the PK case, happy to provide a patch if I can get some advice.
Refer to core issue 19
I have two classes, as below.
When I store (makePersistent) an instance of the container,
the items do not get persisted.
This works fine with datanucleus-rdbms
@PersistenceCapable
class Container {
@PrimaryKey
@Persistent
public String getIdentity() {...}
@Persistent(defaultFetchGroup = "true")
@Join
public List<Item> getItems() {...}
}
@PersistenceCapable
class Item {
@PrimaryKey
@Persistent
public String getIdentity() {...}
}
version: 5.1.0-m1
test: https://github.com/dhakehurst/test-jdo, SimpleTest.MultiplePrimaryKeys()
JDO allows for multiple primary key fields.
The documentation/tutorial for datanucleus-neo4j indicates we can have multiple primary keys.
but when using multiple primary keys, we get an exception (see below).
java.lang.NoSuchMethodError: mydomain.model.MultiKey_PK.setId1(Ljava/lang/Long;)V
at mydomain.model.MultiKey.dnCopyKeyFieldsToObjectId(MultiKey.java)
at org.datanucleus.identity.IdentityManagerImpl.getApplicationId(IdentityManagerImpl.java:461)
at org.datanucleus.ExecutionContextImpl.newObjectId(ExecutionContextImpl.java:3705)
at org.datanucleus.state.StateManagerImpl.setIdentity(StateManagerImpl.java:2305)
at org.datanucleus.state.StateManagerImpl.initialiseForPersistentNew(StateManagerImpl.java:482)
at org.datanucleus.state.StateManagerImpl.initialiseForPersistentNew(StateManagerImpl.java:122)
at org.datanucleus.state.ObjectProviderFactoryImpl.newForPersistentNew(ObjectProviderFactoryImpl.java:218)
at org.datanucleus.ExecutionContextImpl.persistObjectInternal(ExecutionContextImpl.java:2013)
at org.datanucleus.ExecutionContextImpl.persistObjectWork(ExecutionContextImpl.java:1857)
at org.datanucleus.ExecutionContextImpl.persistObject(ExecutionContextImpl.java:1712)
at org.datanucleus.api.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:712)
at org.datanucleus.api.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:738)
at org.datanucleus.test.SimpleTest.MultiplePrimaryKeys(SimpleTest.java:201)
Hi!
We already have the following Filter methods,
.eq() => equals to
.ne() => not equal to
.startsWith() => begins with
.matches() => exact value
Can we have method to search for string which contains a string value?
For instance, if a string like Appletogether
, searching for toget
is true.
I have not seen the method for that.
If a record in Neo4j doesn't have a column that maps on to a primitive field in the current Persistable object then it exits with a NotFoundException. We should check on "hasProperty" before blindly returning the value, like is done for String and other Object based field types
Allow the user to do
pm.newQuery("cypher", "MATCH (m:Movie {title:"The Matrix"})<-[:ACTS_IN]-(actor) WHERE actor.name =~ '.*s$' RETURN actor.name ;");
or
em.createNativeQuery("MATCH (m:Movie {title:"The Matrix"})<-[:ACTS_IN]-(actor) WHERE actor.name =~ '.*s$' RETURN actor.name ;");
List<? extends Persistable> result = jdoQuery.executeList(); //or jdoQuery.execute();
if this returns a LazyLoadQueryResult, with no items in the result,
calling, result.size(), result.isEmpty(), etc.
results in an Exception, see stacktrace below.
The problem might be in "LazyLoadQueryResult.getNextObject()" which calls 'next' without protecting it with a call to 'hasNext'
java.util.NoSuchElementException: next on empty iterator
at scala.collection.Iterator$$anon$2.next(Iterator.scala:39)
at scala.collection.Iterator$$anon$2.next(Iterator.scala:37)
at org.neo4j.cypher.internal.compiler.v3_0.ClosingIterator$$anonfun$next$1.apply(ResultIterator.scala:71)
at org.neo4j.cypher.internal.compiler.v3_0.ClosingIterator$$anonfun$next$1.apply(ResultIterator.scala:70)
at org.neo4j.cypher.internal.compiler.v3_0.ClosingIterator$$anonfun$failIfThrows$1.apply(ResultIterator.scala:93)
at org.neo4j.cypher.internal.compiler.v3_0.ClosingIterator.decoratedCypherException(ResultIterator.scala:102)
at org.neo4j.cypher.internal.compiler.v3_0.ClosingIterator.failIfThrows(ResultIterator.scala:91)
at org.neo4j.cypher.internal.compiler.v3_0.ClosingIterator.next(ResultIterator.scala:70)
at org.neo4j.cypher.internal.compiler.v3_0.ClosingIterator.next(ResultIterator.scala:48)
at org.neo4j.cypher.internal.compiler.v3_0.PipeExecutionResult.next(PipeExecutionResult.scala:75)
at org.neo4j.cypher.internal.compiler.v3_0.PipeExecutionResult$$anon$2.next(PipeExecutionResult.scala:68)
at org.neo4j.cypher.internal.compiler.v3_0.PipeExecutionResult$$anon$2.next(PipeExecutionResult.scala:66)
at org.neo4j.cypher.internal.compatibility.ExecutionResultWrapperFor3_0$$anon$1$$anonfun$next$1.apply(CompatibilityFor3_0.scala:240)
at org.neo4j.cypher.internal.compatibility.ExecutionResultWrapperFor3_0$$anon$1$$anonfun$next$1.apply(CompatibilityFor3_0.scala:240)
at org.neo4j.cypher.internal.compatibility.exceptionHandlerFor3_0$.runSafely(CompatibilityFor3_0.scala:117)
at org.neo4j.cypher.internal.compatibility.ExecutionResultWrapperFor3_0$$anon$1.next(CompatibilityFor3_0.scala:239)
at org.neo4j.cypher.internal.compatibility.ExecutionResultWrapperFor3_0$$anon$1.next(CompatibilityFor3_0.scala:233)
at org.neo4j.cypher.internal.javacompat.ExecutionResult.next(ExecutionResult.java:241)
at org.datanucleus.store.neo4j.query.LazyLoadQueryResult.getNextObject(LazyLoadQueryResult.java:266)
at org.datanucleus.store.neo4j.query.LazyLoadQueryResult.getSizeUsingMethod(LazyLoadQueryResult.java:209)
at org.datanucleus.store.query.AbstractQueryResult.size(AbstractQueryResult.java:357)
at org.datanucleus.store.query.AbstractQueryResult.isEmpty(AbstractQueryResult.java:299)
at org.datanucleus.store.neo4j.query.LazyLoadQueryResult.getNextObject(LazyLoadQueryResult.java:266)
at org.datanucleus.store.neo4j.query.LazyLoadQueryResult.getSizeUsingMethod(LazyLoadQueryResult.java:209)
at org.datanucleus.store.query.AbstractQueryResult.size(AbstractQueryResult.java:357)
at org.datanucleus.store.query.AbstractQueryResult.isEmpty(AbstractQueryResult.java:299)
If we allowed backed SCO collections we would be able to see the collection operations such as add, delete, set etc and so manage the Relationship objects directly
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.