Giter Club home page Giter Club logo

spring-data-gremlin's Introduction

MIT License Build Status codecov

❗❗❗

We have deprecated Spring Data Gremlin. We recommend that you use the TinkerPop driver to query Cosmos DB with Gremlin API or use azure-spring-boot-starter-cosmos to query Cosmos DB with Spring Data SQL API. If you would like us to continue supporting Spring Data Gremlin, please tell us how you are using Spring Data Gremlin for Cosmos DB and how important it is to you, by voting on this issue with the thumbs up emoji.

Spring Data Gremlin

Spring Data Gremlin provides initial Spring Data support for those databases using Gremlin query language. With annotation oriented programming model, it simplified the mapping to the database entity. It also provides supports for basic and custom query.

This project works with any Gremlin-compatible data store, and also with Azure Cosmos DB. Cosmos is a globally-distributed database service that allows developers to work with data using a variety of standard APIs, such as Graph, MongoDB, and SQL. Spring Data Gremlin provides a delightful experience to interact with Azure Cosmos DB Graph API.

Spring Data Version Support

Version mapping between spring boot and spring-data-gremlin:

Spring boot version spring-data-gremlin version
version Maven Central
version Maven Central
version Maven Central
version Maven Central

TOC

Welcome To Contribute

Contribution is welcome. Please follow this instruction to contribute code.

Sample Code

Please refer to sample project here.

Spring data version support

This repository only supports Spring Data 2.x.

Feature List

  • Spring Data CRUDRepository basic CRUD functionality
    • save
    • findAll
    • findById
    • deleteAll
    • deleteById
  • Spring Data @Id annotation. There're 2 ways to map a field in domain class to id field of a database entity.
    • annotate a field in domain class with @Id
    • set name of this field to id
  • Default annotaion
    • @Vertex maps an Object to a Vertex
    • @VertexSet maps a set of Vertex
    • @Edge maps an Object to an Edge
    • @EdgeSet maps to a set of Edge
    • @EdgeFrom maps to the head Vertex of an Edge
    • @EdgeTo maps to the tail Vertex of an Edge
    • @Graph maps to an Object to a Graph
  • Supports advanced operations
    • <T> T findVertexById(Object id, Class<T> domainClass);
    • <T> T findEdgeById(Object id, Class<T> domainClass);
    • <T> boolean isEmptyGraph(T object)
    • long vertexCount()
    • long edgeCount()
  • Supports Spring Data custom query find operation, e.g., findByAFieldAndBField
  • Supports any class type in domain class including collection and nested type.

Quick Start

Add the dependency

spring-data-gremlin is published on Maven Central Repository.
If you are using Maven, add the following dependency.

<dependency>
    <groupId>com.microsoft.spring.data.gremlin</groupId>
    <artifactId>spring-data-gremlin</artifactId>
    <version>2.1.7</version>
</dependency>

Setup Configuration

Setup application.yml file.(Use Azure Cosmos DB Graph as an example.)

gremlin:
  endpoint: url-of-endpoint 
  port: 443
  username: /dbs/your-db-name/colls/your-collection-name
  password: your-password
  telemetryAllowed: true # set false to disable telemetry

Define an entity

Define a simple Vertex entity with @Vertex.

@Vertex
public class Person {

    @Id
    private String id;

    private String name;

    private String age;

    ...
}

Define a simple Edge entity with @Edge.

@Edge
public class Relation {

    @Id
    private String id;

    private String name;

    @EdgeFrom
    private Person personFrom;

    @EdgeTo
    private Person personTo;

    ...
}

Define a simple Graph entity with @Graph.

@Graph
public class Network {

    @Id
    private String id;

    public Network() {
        this.edges = new ArrayList<Object>();
        this.vertexes = new ArrayList<Object>();
    }

    @EdgeSet
    private List<Object> edges;

    @VertexSet
    private List<Object> vertexes;
    
    ...
}

Create repositories

Extends DocumentDbRepository interface, which provides Spring Data repository support.

import GremlinRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PersonRepository extends GremlinRepository<Person, String> {
        List<Person> findByName(String name); 
}

findByName method is custom query method, it will find the person with the name property.

Create an Application class

Here create an application class with all the components

@SpringBootApplication
public class SampleApplication implements CommandLineRunner {

    @Autowired
    private PersonRepository repository;

    public static void main(String[] args) {
        SpringApplication.run(SampleApplication.class, args);
    }

    public void run(String... var1) throws Exception {

        private final Person testUser = new Person("PERSON_ID", "PERSON_NAME", "PERSON_AGE");

        repository.deleteAll();
        repository.save(testUser);

        ... 
    }
}

Autowired UserRepository interface, then can do save, delete and find operations. Spring Data Azure Cosmos DB uses the DocumentTemplate to execute the queries behind find, save methods. You can use the template yourself for more complex queries.

Filing Issues

If you encounter any bug, please file an issue here.

To suggest a new feature or changes that could be made, file an issue the same way you would for a bug.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Data/Telemetry

This project collects usage data and sends it to Microsoft to help improve our products and services. Read our privacy statement to learn more.

spring-data-gremlin's People

Contributors

brunoborges avatar chenrujun avatar dbeaudry92 avatar dependabot[bot] avatar fabiencoppens avatar gguttikonda avatar incarnation-p-lee avatar jwalter avatar karlerickson avatar kschulst avatar matthew-dong avatar microsoftopensource avatar msftgits avatar rekon avatar saragluna avatar seanli1988 avatar sophiaso avatar superrdean avatar yungezz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-data-gremlin's Issues

How to connect gremlin into janusgraph

I already put cassandra server completely with address, username and password that backend of janusgraph, but still can't connect. Do You have guideline for setting configuration to connect into janusgraph?

Thanks

Refine the database AbstractConfiguration.

Your issue may already be reported! Please search before creating a new one.

Expected Behavior

  • placeholder

Current Behavior

  • placeholder

Possible Solution

  • placeholder

Steps to Reproduce (for bugs)

  • step-1
  • step-2
  • ...

Snapshot Code for Reproduce

@SpringBootApplication
public class Application {
    public static void main(String... args) {
        SpringApplication.run(Application.class, args);
    }
}

Branch

  • placeholder

Your Environment

  • Version used:
  • Operating System and version (desktop or mobile):
  • SDK version:

add support for Spring-boot 2.1.0

The repository mechanism is broken when you take spring boot 2.1.0 as a parent.

You have defined query method in the repository but you don't have any query lookup strategy defined. The infrastructure apparently does not support query methods!

If I downgrade to Spring-boot 2.0.6.REALEASE it's ok

Adding new Map/List/Set variable to Java entity throws NPE

I'm new to Gremlin and graph DB.
Initially I created a Java entity to hold three variables like below

`@Data
@vertex
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
@id
private String id;

private String name;

private Integer age;

}`

Using the above bean few Vertices were saved sucessfully in Gremlin(Azure cosmosDB) .
Added a new property called joiningDate to Java Entity and saved few objects but on querying using findAll throws NPE.

`@Data
@vertex
@AllArgsConstructor
@NoArgsConstructor
public class Employee {

@Id
private String id;

private String name;

private Integer age;

private Map departments;

}
`

Expected Behavior

NPE shouldn't be thrown and the objects correctly mapped to the corresponding Java Entity/bean

Current Behavior

Null Pointer in AbstractGremlinSourceReader due to field not present in some of the vertex of GraphDB

Possible Solution

In AbstractGremlinSourceReader class, in the readProperty method there could be null check in the objectmapper for variable 'value' and if null its correspoding type be assigned to null.

Steps to Reproduce (for bugs)

Step1: Use the First Employee Java Object and persist an vertex

GremlinTemplate secondaryGremlinTemplate = new GremlinTemplate(secondaryGremlinFactory,mappingGremlinConverter);
Employee employeeInsert = new Employee();
employeeInsert.setId("Emp1");
employeeInsert.setName("Employee1");
employeeInsert.setAge(20);
secondaryGremlinTemplate.insert(employeeInsert);

Step2: Query using the following code to query using findAll

Iterable<Employee> employee = secondaryGremlinTemplate.findAll(Employee.class);
System.out.println("Employee->" + employee);
for (Employee emp1 : employee) {
System.out.println("Employee->" + emp1.getId());
}

All dandy
Step3: Use the second Employee object and pesist a new vertex

Employee employee2Insert = new Employee();
employee2Insert.setId("SecEmp2");
employee2Insert.setName("SecEmployee2");
employee2Insert.setAge(30);
Map<String,String> map = new HashMap<>();
map.put("key1","val1");
employee2Insert.setDepartments(map);
secondaryGremlinTemplate.insert(employee2Insert);

Step4: Use the following code to query using findAll

Iterable<Employee> employee2Itr = secondaryGremlinTemplate.findAll(Employee.class);
System.out.println("Employee->" + employee2Itr);
for (Employee emp2 : employee) {
	System.out.println("Employee->" + emp2.getId());

Throws NPE on findAll

Snapshot Code for Reproduce

@SpringBootApplication
public class Application {
    public static void main(String... args) {
        SpringApplication.run(Application.class, args);
    }
}

Branch

Your Environment

  • Version used: 2.0.0
  • Operating System and version (desktop or mobile): Microsoft with Azure cosmosDB
  • SDK version:

Transactional support?

Is there a way to handle transactions like the old JDBC fashion way?
this.networkRepo.save(this.network); what happens if some vertexes were successfully saved and some were not. How can we roll it back?

SSL errors if connecting to an AWWS Neptune instance

Your issue may already be reported! Please search before creating a new one.

Expected Behavior

  • spring-data-gremlin can be used with AWS Neptune databases and the corresponding http endpoints

Current Behavior

  • spring-data-gremlin cannot be used with AWS Neptune databases and the corresponding http endpoints since SSL errors occur during build time

Possible Solution

  • Add possibility to disable SSL for the Gremlin cluster configuration.
  • It seems like SSL is enabled by default, cf. the GremlinFactory.java implementation/. Did I miss a configuration option?

Steps to Reproduce (for bugs)

The source code used for the tests can be found at spanierm/aws-neptune-spring-boot

  • login to AWS and create the Cloudformation stack defined in cf-template.yaml
  • change the endpoint in src/main/resources/application.yml to the newly created AWS Neptune endpoint
  • copy the source code to the newly created AWS EC2 instance
  • access the AWS EC2 instance and set export TERM=xterm-color
  • build the application with ./gradlew clean build

As a result, you get the following errors:

com.github.spanierm.awsneptunespringboot.AwsNeptuneSpringBootApplicationTests > contextLoads FAILED
    java.lang.IllegalStateException
        Caused by: java.lang.IllegalStateException
            Caused by: java.lang.RuntimeException
                Caused by: java.lang.RuntimeException
                    Caused by: java.util.concurrent.TimeoutException
2018-10-14 17:39:09.834  WARN 24768 --- [n-driver-loop-1] o.a.tinkerpop.gremlin.driver.Cluster     : SSL configured without a trustCertChainFile and thus trusts all certificates without verification (not suitable for production)
2018-10-14 17:39:09.844 ERROR 24768 --- [n-driver-loop-1] o.a.t.g.d.Handler$GremlinResponseHandler : Could not process the response

io.netty.handler.codec.DecoderException: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 485454502f312e31203430302042616420526571756573740d0a436f6e74656e742d547970653a206170706c69636174696f6e2f6a736f6e0d0a436f6e74656e742d4c656e6774683a203133340d0a0d0a7b22726571756573744964223a2231386233333964342d383463372d373131652d613336302d646532653030313465336131222c22636f6465223a2242616452657175657374457863657074696f6e222c2264657461696c65644d657373616765223a22556e6578706563746564206572726f722072656164696e67207468652055524c227d
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:628) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:563) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:480) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
Caused by: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 485454502f312e31203430302042616420526571756573740d0a436f6e74656e742d547970653a206170706c69636174696f6e2f6a736f6e0d0a436f6e74656e742d4c656e6774683a203133340d0a0d0a7b22726571756573744964223a2231386233333964342d383463372d373131652d613336302d646532653030313465336131222c22636f6465223a2242616452657175657374457863657074696f6e222c2264657461696c65644d657373616765223a22556e6578706563746564206572726f722072656164696e67207468652055524c227d
        at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1178) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1243) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        ... 15 common frames omitted

2018-10-14 17:39:09.859  WARN 24768 --- [n-driver-loop-1] o.a.tinkerpop.gremlin.driver.Cluster     : SSL configured without a trustCertChainFile and thus trusts all certificates without verification (not suitable for production)
2018-10-14 17:39:09.868 ERROR 24768 --- [n-driver-loop-1] o.a.t.g.d.Handler$GremlinResponseHandler : Could not process the response

io.netty.handler.codec.DecoderException: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 485454502f312e31203430302042616420526571756573740d0a436f6e74656e742d547970653a206170706c69636174696f6e2f6a736f6e0d0a436f6e74656e742d4c656e6774683a203133340d0a0d0a7b22726571756573744964223a2233386233333964342d383464322d643736352d663138362d633031663534356166633963222c22636f6465223a2242616452657175657374457863657074696f6e222c2264657461696c65644d657373616765223a22556e6578706563746564206572726f722072656164696e67207468652055524c227d
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:628) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:563) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:480) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [netty-all-4.1.29.Final.jar:4.1.29.Final]
        at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
Caused by: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 485454502f312e31203430302042616420526571756573740d0a436f6e74656e742d547970653a206170706c69636174696f6e2f6a736f6e0d0a436f6e74656e742d4c656e6774683a203133340d0a0d0a7b22726571756573744964223a2233386233333964342d383464322d643736352d663138362d633031663534356166633963222c22636f6465223a2242616452657175657374457863657074696f6e222c2264657461696c65644d657373616765223a22556e6578706563746564206572726f722072656164696e67207468652055524c227d
        at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1178) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1243) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428) ~[netty-all-4.1.29.Final.jar:4.1.29.Final]
        ... 15 common frames omitted


1 test completed, 1 failed

Connections to the AWS Neptune instance do work if you use Gremlin directly to connect to it:

  • change the file src/main/kotlin/com/github/spanierm/awsneptunespringboot/AwsNeptuneSpringBootApplication.kt and uncomment the first @Component (GremlinDirectConnection) while also comment out the second @Component (SpringDataGremlinConnection)
  • build the application with ./gradlew clean build
  • run the application with java -jar build/libs/aws-neptune-spring-boot-0.0.1-SNAPSHOT.jar

The output looks as follows:

[ec2-user@ip-172-30-1-182 aws-neptune-spring-boot]$ ./gradlew clean build

> Task :test
2018-10-14 17:41:59.066  INFO 24951 --- [      Thread-14] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@17eabf54: startup date [Sun Oct 14 17:41:46 UTC 2018]; root of context hierarchy

BUILD SUCCESSFUL in 24s
7 actionable tasks: 7 executed
[ec2-user@ip-172-30-1-182 aws-neptune-spring-boot]$ java -jar build/libs/aws-neptune-spring-boot-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.5.RELEASE)

2018-10-14 17:42:18.044  INFO 24991 --- [           main] .g.s.a.AwsNeptuneSpringBootApplicationKt : Starting AwsNeptuneSpringBootApplicationKt on ip-172-30-1-182 with PID 24991 (/home/ec2-user/aws-neptune-spring-boot/build/libs/aws-neptune-spring-boot-0.0.1-SNAPSHOT.jar started by ec2-user in /home/ec2-user/aws-neptune-spring-boot)
2018-10-14 17:42:18.073  INFO 24991 --- [           main] .g.s.a.AwsNeptuneSpringBootApplicationKt : No active profile set, falling back to default profiles: default
2018-10-14 17:42:18.902  WARN 24991 --- [kground-preinit] o.s.h.c.j.Jackson2ObjectMapperBuilder    : For Jackson Kotlin classes support please add "com.fasterxml.jackson.module:jackson-module-kotlin" to the classpath
2018-10-14 17:42:19.044  INFO 24991 --- [           main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@5f5a92bb: startup date [Sun Oct 14 17:42:19 UTC 2018]; root of context hierarchy
2018-10-14 17:42:22.697  INFO 24991 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2018-10-14 17:42:22.783  INFO 24991 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2018-10-14 17:42:22.783  INFO 24991 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.34
2018-10-14 17:42:22.823  INFO 24991 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
2018-10-14 17:42:23.154  INFO 24991 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-10-14 17:42:23.155  INFO 24991 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 4131 ms
2018-10-14 17:42:23.338  INFO 24991 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Servlet dispatcherServlet mapped to [/]
2018-10-14 17:42:23.346  INFO 24991 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-10-14 17:42:23.350  INFO 24991 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-10-14 17:42:23.350  INFO 24991 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-10-14 17:42:23.350  INFO 24991 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
AI: INFO 14-10-2018 17:42, 1: Configuration file has been successfully found as resource
AI: ERROR 14-10-2018 17:42, 1: Failed to create com.microsoft.applicationinsights.web.internal.perfcounter.WebPerformanceCounterModule, com.microsoft.applicationinsights.web.internal.perfcounter.WebPerformanceCounterModule
AI: INFO 14-10-2018 17:42, 1: Configuration file has been successfully found as resource
AI: ERROR 14-10-2018 17:42, 1: Failed to create com.microsoft.applicationinsights.web.internal.perfcounter.WebPerformanceCounterModule, com.microsoft.applicationinsights.web.internal.perfcounter.WebPerformanceCounterModule
2018-10-14 17:42:27.925  INFO 24991 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-14 17:42:28.503  INFO 24991 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@5f5a92bb: startup date [Sun Oct 14 17:42:19 UTC 2018]; root of context hierarchy
2018-10-14 17:42:28.675  INFO 24991 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[],methods=[POST]}" onto public java.lang.String com.github.spanierm.awsneptunespringboot.AwsNeptuneController.executeGremlinQuery(java.lang.String)
2018-10-14 17:42:28.682  INFO 24991 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-10-14 17:42:28.684  INFO 24991 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-10-14 17:42:28.760  INFO 24991 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-14 17:42:28.761  INFO 24991 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-14 17:42:29.331  INFO 24991 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-10-14 17:42:29.427  INFO 24991 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2018-10-14 17:42:29.436  INFO 24991 --- [           main] .g.s.a.AwsNeptuneSpringBootApplicationKt : Started AwsNeptuneSpringBootApplicationKt in 12.924 seconds (JVM running for 14.155)
2018-10-14 17:42:29.881  INFO 24991 --- [           main] o.a.tinkerpop.gremlin.driver.Connection  : Created new connection for ws://neptunedbinstance-<SOME_INSTANCE>.eu-west-1.neptune.amazonaws.com:8182/gremlin
2018-10-14 17:42:29.894  INFO 24991 --- [           main] o.a.tinkerpop.gremlin.driver.Connection  : Created new connection for ws://neptunedbinstance-<SOME_INSTANCE>.eu-west-1.neptune.amazonaws.com:8182/gremlin
2018-10-14 17:42:29.894  INFO 24991 --- [           main] o.a.t.gremlin.driver.ConnectionPool      : Opening connection pool on Host{address=neptunedbinstance-<SOME_INSTANCE>.eu-west-1.neptune.amazonaws.com/172.30.2.57:8182, hostUri=ws://neptunedbinstance-<SOME_INSTANCE>.eu-west-1.neptune.amazonaws.com:8182/gremlin} with core size of 2
{name=[Custom id vertex 1]}
{name=[Custom id vertex 2]}
{Name=[Justin]}
2018-10-14 17:42:30.153  INFO 24991 --- [           main] o.a.t.gremlin.driver.ConnectionPool      : Signalled closing of connection pool on Host{address=neptunedbinstance-<SOME_INSTANCE>.eu-west-1.neptune.amazonaws.com/172.30.2.57:8182, hostUri=ws://neptunedbinstance-<SOME_INSTANCE>.eu-west-1.neptune.amazonaws.com:8182/gremlin} with core size of 2

Your Environment

  • Amazon Linux AMI 2018.03.0.20180508 x86_64 HVM GP2
  • Gradle 4.8.1
  • Kotlin 1.2.51

Potential performance issue at the save in the GremlinTemplate and request of the clarification of the usage of the @Graph

  1. In the save method, Line 265, when saving a graph the if condition calls isEmptyGraph method, However this will send the g.V() query to the server and according to what Tinkerpop document says, it will iterate over all vertices. If all it needs to verify is whether there is any vertex exists, shouldn't it use g.V().limit(1) query instead?

  2. It looks like the current design of the save of a domain object with @graph is very limited. Given the aforementioned condition check, it doesn't insert the graph object if there is something created in DB and does an update instead. However, the update process of the graph object only writes all the properties of vertex and edge to DB and it doesn't update the relationship(from/to) on the edges. (see GremlinScriptLiteralGraph class -> generateUpdateScript method) Is there any planned enhancement to support updating the relationship in the @graph domain object as well?

  3. Is it possible to drop the isEmptyGraph check? It doesn't really make sense to be able to inserting a graph of vertices and edges only when there is nothing in the DB. I think it is very common to persist a (sub)graph of object at anytime.

Edge repository deleteAll operation should not delete vertex in graph

Expected Behavior

  • DeleteAll edge should leave vertex in graph

Current Behavior

  • DeleteAll edge will delete both vertexes and edges in graph

Possible Solution

  • Handle edge and vertex delete all respectively.

Steps to Reproduce (for bugs)

  • screate 2 vertex and 1 edge connected
  • deleteAll from edge
  • findById vertex will return optional.empty()

Snapshot Code for Reproduce

        this.personRepo.save(this.person);
        this.projectRepo.save(this.project);
        this.relationshipRepo.save(this.relationship);

        this.relationshipRepo.deleteAll();

        this.personRepo.findById(this.persion.getId()); // will return Optional.empty()

Branch

  • master

Your Environment

  • Version used:
  • Operating System and version (desktop or mobile):
  • SDK version:

Save java class instance will ignore its parent class field.

Your issue may already be reported! Please search before creating a new one.
Current implementation will ignore the fields from super class.

Expected Behavior

  • Should save the field from super class.

Current Behavior

  • These fields from super class ignored.

Possible Solution

  • placeholder

Steps to Reproduce (for bugs)

  • Define one class as super class
  • Define another class as child class extend super class.
  • repository.save(child-class-instance)

Snapshot Code for Reproduce

@SpringBootApplication
public class Application {
    public static void main(String... args) {
        SpringApplication.run(Application.class, args);
    }
}

Branch

  • master

Your Environment

  • Version used:
  • Operating System and version (desktop or mobile):
  • SDK version:

How to query/get the related vertexes /nested properties

Expected Behavior

  • get Vertexes which have relations to other vertexes in Vertex or Edge-Repository

Current Behavior

  • I can't query vertices based on relation with other vertices (e.g. Developer Vertex, build (edge), Software (Vertex) - how to query all Software which were built by developer John?

Possible Solution

  • enabling Gremlin native queries with @query Annotation?

Exception "No such property: g for class: Script" when working with JanusGraph on IBM Cloud

Hi! I created a JanusGraph Server using IBM Compose and tried to run your example on it.

Connection with my remote JanusGraph server is established, but any method that works with data in my graph fails with exception: com.microsoft.spring.data.gremlin.exception.GremlinQueryException: unable to complete query from gremlin; nested exception is java.util.concurrent.ExecutionException: org.apache.tinkerpop.gremlin.driver.exception.ResponseException: No such property: g for class: Script22

What am I doing wrong? From Gremlin console everything works fine.

Support for numeric vertex ids?

Hi.
I see in GremlinUtils.getIdField that only String ids are supported:

} else if (idField.getType() != String.class) {
            throw new GremlinInvalidEntityIdFieldException("the type of @Id/id field should be String");
        }

Are there any plans to support numeric id types? We're hoping to use spring-data-gremlin on top of JanusGraph, which only supports numeric ids.

Does not work with JanusGraph

Your issue may already be reported! Please search before creating a new one.

Expected Behavior

  • Must work with other Graph databases where gremlin is supported

Current Behavior

  • Tried with Janusgraph running and connecting to gremlin server . When Application boots up, connection is established and no errors, but when save operation is being performed , it gives timeout exception. below are the logs

java.util.concurrent.TimeoutException: Timed out while waiting for an available host - check the client configuration and connectivity to the server if this message persists
at org.apache.tinkerpop.gremlin.driver.Client$ClusteredClient.chooseConnection(Client.java:499) ~[gremlin-driver-3.2.4.jar:3.2.4]
at org.apache.tinkerpop.gremlin.driver.Client.submitAsync(Client.java:305) ~[gremlin-driver-3.2.4.jar:3.2.4]
at org.apache.tinkerpop.gremlin.driver.Client.submitAsync(Client.java:242) ~[gremlin-driver-3.2.4.jar:3.2.4]
at org.apache.tinkerpop.gremlin.driver.Client.submit(Client.java:212) ~[gremlin-driver-3.2.4.jar:3.2.4]
at org.apache.tinkerpop.gremlin.driver.Client.submit(Client.java:198) ~[gremlin-driver-3.2.4.jar:3.2.4]
at com.microsoft.spring.data.gremlin.query.GremlinTemplate.lambda$executeQuery$0(GremlinTemplate.java:74) ~[spring-data-gremlin-2.0.0.jar:na]
at java.util.Arrays$ArrayList.forEach(Arrays.java:3880) ~[na:1.8.0_171]
at com.microsoft.spring.data.gremlin.query.GremlinTemplate.executeQuery(GremlinTemplate.java:74) ~[spring-data-gremlin-2.0.0.jar:na]
at com.microsoft.spring.data.gremlin.query.GremlinTemplate.deleteAll(GremlinTemplate.java:86) ~[spring-data-gremlin-2.0.0.jar:na]
at com.microsoft.spring.data.gremlin.repository.support.SimpleGremlinRepository.deleteAll(SimpleGremlinRepository.java:116) ~[spring-data-gremlin-2.0.0.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:377) ~[spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200) ~[spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:629) ~[spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:593) ~[spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578) ~[spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at com.sun.proxy.$Proxy72.deleteAll(Unknown Source) ~[na:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at com.sun.proxy.$Proxy72.deleteAll(Unknown Source) ~[na:na]
at com.neuron.controllers.HomeController.saveInfo(HomeController.java:20) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.31.jar:8.5.31]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_171]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_171]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.31.jar:8.5.31]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_171]

Steps to Reproduce (for bugs)

  • step-1
  • step-2
  • ...

Snapshot Code for Reproduce

I used example existing in this repo.

Your Environment

  • Version used:2.0.0
  • Operating System and version (desktop or mobile):
  • SDK version:

entityInformation do not handle Id carefully

Expected Behavior

  • Can handle @Id, field without @Id within name id.

Current Behavior

  • Only take care of field name id.

Possible Solution

  • Add specific code handle when parse idField in EntityInforamation, and recover field name when read.

Steps to Reproduce (for bugs)

  • step-1
  • step-2
  • ...

Snapshot Code for Reproduce

public class Domain {
    @Id
    private String name;
}

Branch

  • master

Your Environment

  • Version used:
  • Operating System and version (desktop or mobile):
  • SDK version: 1.8 and above

spring-data-gremlin-example project in example folder build fails.

mvn clean install -U

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Spring Data gremlin - Example 0.0.1.BUILD-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for com.microsoft.spring.data.gremlin:spring-data-gremlin:jar:0.0.1-SNAPSHOT is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.219 s
[INFO] Finished at: 2018-06-12T16:15:27+05:30
[INFO] Final Memory: 16M/39M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project spring-data-gremlin-example: Could not resolve dependencies for project com.microsoft.spring.data.gremlin.examples:spr
ing-data-gremlin-example:jar:0.0.1.BUILD-SNAPSHOT: Could not find artifact com.microsoft.spring.data.gremlin:spring-data-gremlin:jar:0.0.1-SNAPSHOT -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException

Also i could not find spring-data-gremlin in maven central repository and the following dependency addition fails.

<groupId>com.microsoft.azure</groupId>
<artifactId>spring-data-gremlin</artifactId>
<version>2.x.x</version>

what is the version as in place of 2.x.x ?

Need for @Graph

Is the Network class needed?
The use of the Network class annotated with @graph seems like it may be an obstacle for large graphs.

Support @Link or @ManyToOne equivalent

I would need a way to add inside a @Vertex object a field pointing to another @Vertex which would be the entity that can be retrieved via an @Edge whose label is the name of the object field.

https://github.com/zifnab87/spring-data-gremlin implement this via a @Link annotation.

Example:

@Vertex
public class Person {
    @Id
    private String id;

    @Link("livesAt")
    private Address address;

    @Link
    private Address defaultShipTo;
}

@Vertex
public class Address {
    @Id
    private String id;

    private String city;

    private String street;
}

Here a Person will retrieve a vertex Address via an edge labelled "livesAt" and another vertex Address via an edge labelled "defaultShipTo" into respective fields.

Refine the generator of GremlinQuery

The current design of GremlinQuery looks like strategy, but there is assumption here, you need to set the generator before generation. It is more elegant if separate the generator from GremlinQuery. The code may looks create generator, then generate on query.

    @Override
    public <T> List<T> find(@NonNull GremlinQuery query, @NonNull Class<T> domainClass) {
        @SuppressWarnings("unchecked") final GremlinEntityInformation info = new GremlinEntityInformation(domainClass);
        final GremlinSource source = info.getGremlinSource();

        query.setScriptGenerator(new QueryFindScriptGenerator());

        final List<String> queryList = query.doSentenceGenerate(domainClass);
        final List<Result> results = this.executeQuery(queryList);

        if (results.isEmpty()) {
            return Collections.emptyList();
        }

        return this.recoverDomainList(source, results, domainClass, info.isEntityEdge());
    }

Gremlin driver throwing connection timeout exception after several requests

Expected Behavior

Spring data gremlin driver throws timeout exception after serving several request.If the latest version of gremlin - driver is used,it automatically reconnects and works as expected.

Current Behavior

After several requests get the following error : gets the error - "java.lang.RuntimeException: java.util.concurrent.TimeoutException: Timed out while waiting for an available host - check the client configuration and connectivity to the server if this message persists".

Possible Solution

The issue is with the gremlin-driver version used by the spring-data-gremlin. Please refer apache issues to find the issue with used version of gremlin driver(version - 3.2.4) - https://issues.apache.org/jira/browse/TINKERPOP-2044
They have fixed the issue in the latest gremlin-driver versions.Please release a new spring -data gremlin version with the following dependency :
org.apache.tinkerpop
gremlin-driver
3.4.0

3.4.0 or higher version can be used.

Steps to Reproduce (for bugs)

Reference : https://issues.apache.org/jira/browse/TINKERPOP-2044

Snapshot Code for Reproduce

@SpringBootApplication
public class Application {
    public static void main(String... args) {
        SpringApplication.run(Application.class, args);
    }
}

Branch

master

Your Environment

  • Version used:2.0.0
  • Operating System and version (desktop or mobile): Linux
  • SDK version: 2.0.0

Query method creation with keyword

New feature on Query Method Creation with Keyword. List the keyword and example in below.

  • AND
List<T> findByNameAndCount(String name, int count);
  • OR
List<T> findByNameOrCount(String name, int count);
  • Is_EQUALS
List<T> findByName(String name);
  • AFTER
List<T> findByCreateAtAfter(Date expireDate); // Only Date type is supported for now.
  • BEFORE
List<T> findByCreateAtBefore(Date expiryDate); // Only Date type is supported for now.
  • CONTAINING
  • BETWEEN
List<T> findByCreateAtBetween(Date start, Date end);
  • ENDING_WITH
  • EXISTS
List<T> findByEnabledExists();
  • FALSE
  • GREATER_THAN
  • GREATER_THAN_EQUALS
  • IN
  • IS
  • IS_NOT_NULL
  • IS_NULL
  • LESS_THAN
  • LESS_THAN_EQUAL
  • LIKE
  • NEAR
  • NOT
  • NOT_IN
  • NOT_LIKE
  • REGEX
  • STARTING_WITH
  • TRUE
  • WITHIN

Your Environment

  • Operating System and version (desktop or mobile):
  • SDK version: 1.8+

Collection annotation

I can see the need for annotating a collection of vertex to indicate the edges involved. There are cases when you have edges that don't have attributes and you don't need a separate entity class to represent that edge. A lot like @manytomany in JPA.

Is GremlinTemplate planned?

Most of the Spring Data projects have a template class that allows closer access to the underlying technology.
GremlinTemplate should provide access to the underlying Graph and traversal API.

Provide information about data collection and how to disable it

The section Data/Telemetry in the README.md says:

This project collects usage data and sends it to Microsoft to help improve our products and services. Read our privacy statement to learn more.

However, the words privacy statement are not a link and do not point anywhere, nor is there another link to the privacy statement.

Also, a search for the word privacy in this repo shows no mention other than the word in the sentence above, from the README.md itself.

Thus, it is unclear:

  • what info is collected
  • where this info is sent
  • how to disable it

Alternatively, why not disable it by default and allow users to opt-in to sharing this information?

0.1.0 endgame

Updating

  • Sample
  • Telemetry
  • OSS Review
  • Readme.md
  • Blog Draft
  • Test
  • Release

Why does @Id fields have to be String?

I'm experimenting spring-data-gremlin, using the tinkerpop gremlin-server as backend. I am playing with the "modern graph" supplied by the gremlin-server, which out of the box the graph has integer type IDs.

image

However, spring-data-gremlin enforces @Id-annotated fields to be String:
https://github.com/Microsoft/spring-data-gremlin/blob/456264b22f527b8ac62a378d8076f36a818ea234/src/main/java/com/microsoft/spring/data/gremlin/common/GremlinUtils.java#L63-L65

What is the reason for only allowing String? It seems that gremlin-server, when running in a default and naïve configuration, non-String IDs are being used.

If I save one of my vertice to the graph, using something like:

personRepository.save(Person.builder().id("123").name("joe").build()));

...I end up with a vertex in the graph with a generated id (e.g. 17), and "id" as a property, like so:

gremlin> :> g.V(17).properties()
==>vp[name->joe]
==>vp[id->123]

Spring boot 2.1.0.RELEASE will result in BeanCreationException

Leverage spring-data-gremlin with spring-boot 2.1.0.RELEASE will result in BeanCreationExcetpion, need to implement lookupstrategy.

Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalStateException: You have defined query method in the repository but you don't have any query lookup strategy defined. The infrastructure apparently does not support query methods!

Reserved property keywords (id, label) require special treatment

(Refer to #131 for a more detailed discussion about this)

spring-data-gremlin surrounds reserved property keywords such as id and label with apostrophes. This results in id and label to be treated as standard properties.

I have tested this on both gremlin-server and aws neptune - with the same result.

Here's an excerpt from my gremlin console when accessing aws neptune:

gremlin> g.addV('Person').property('id', '1').property('name', 'name1')
==>v[aeb27ce1-087a-978c-0eaa-91adb705c355]
gremlin> g.addV('Person').property(id, '2').property('name', 'name2')
==>v[2]
gremlin> g.addV('Person').property(T.id, '3').property('name', 'name3')
==>v[3]

gremlin> g.V('aeb27ce1-087a-978c-0eaa-91adb705c355').properties()
==>vp[id->1]
==>vp[name->name1]
gremlin> g.V('2').properties()
==>vp[name->name2]

gremlin> g.V().has('label', 'Person')
gremlin> g.V().has(label, 'Person')
==>v[2]
==>v[aeb27ce1-087a-978c-0eaa-91adb705c355]
==>v[3]

This issue could be solved by making reserved keywords such as label and id use other templates than today:

public static final String GREMLIN_PRIMITIVE_PROPERTY_STRING = "property('%s', '%s')
public static final String GREMLIN_PRIMITIVE_HAS_STRING = "property('%s', '%s')

Would you be interested if I created a PR to solve this issue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.