How to merge two existing nodes in neo4j using Spring, OGM and #RelationshipEntity - spring

I am using Spring neo4j ogm and I have Entities already saved in database. Now I want to create new relationship between them with spring ogm. Problem is that i have only entities uuid in this moment, and I want to escape getEntityByUuid() which could get me entity object and then repo.save() would do the trick.
If i need to create custom query, can it be in repository in this format:
public interface EntityRepository extends Neo4jRepository<Entity, Long> {
#Query("MATCH (e:Entity {uuid:$0}), (e2:Entity{uuid:$1}) CREATE (e)-[:MENTION{relationshipProperties...}]->(e2)")
boolean createRelationshipBetweenExistingEntities(String entity1uuid, String entity2uuid, RelationshipNeo4j rel);
These are my classes:
public abstract class AbstractEntity {
#Id
#GeneratedValue
private Long id;
}
#RelationshipEntity(type = "MENTION")
public class RelationshipNeo4j extends AbstractEntity {
#Property
protected String type;
#Property
protected LocalDate date;
#StartNode
protected Entity start;
#EndNode
protected Entity end;
}
#NodeEntity
public class Entity extends AbstractEntity {
protected String name;
#Index(unique = true)
protected String uuid;
protected String wikiURL;
protected String description;
#Relationship(type="MENTION")
protected List<RelationshipNeo4j> relationships;
}

This is the closest I came:
#Query("MATCH (e:Entity {uuid:{entity1uuid}}), (e2:Entity{uuid:{entity2uuid}}) CREATE (e)-[r:MENTION{uuid:{relationshipUuid},type:{type},date:{date}}]->(e2) RETURN e,e2,r")
RelationshipNeo4j createRelationshipBetweenExistingEntities(String entity1uuid, String entity2uuid, String relationshipUuid, String type, String date);
We can't inset into query non primitive types:
https://markhneedham.com/blog/2017/12/01/neo4j-cypher-property-values-can-primitive-types-arrays-thereof/

Related

How to Inner Join using Spring Boot JPA / Hibernate in Repository?

I am currently learning spring boot , hibernate and Spring Boot JPA
I developing a Classroom App for coaching centers and institutes .
In it, students enrolled to multiple courses in a single institute
The Student Entity class :
#Entity
#Table(name = "student")
public class Student {
private String name;
private String dob;
private String gender;
private String address;
private String email;
private Integer mobile;
private String joined;
private Integer instID;
#Id
private String studentid;
getters and setters()....
}
Course Table Entity class
#Entity
#Table(name = "courses")
public class Course {
private String name;
private String description;
private String logo;
private String start;
private String end;
private Integer fee;
#Id
private String courseid;
private Integer instID;
getters and setters();
}
Enrolled Classes Table's Entity class
public class EnrolledCourses {
#Id
String enrollID;
String courseid;
String studentid;
Date joined;
getters and setters()...
}
JPA Repository
#Repository
public interface StudentRepository extends CrudRepository<Student, String> {
Student findTopByInstIDOrderByStudentidDesc(int instID);
}
#Repository
public interface CourseRepository extends CrudRepository<Course,String> {
}
#Repository
public interface EnrolledRepository extends CrudRepository<Course,String> {
}
My Need
Now I am retrieving enrolled students for a given course in a given institute... by using this MySQL query
SELECT
`enrolled_courses.enrollID`,
`student.name`, `student.studentid`
FROM `enrolled_courses`
INNER JOIN `student`
WHERE
`enrolled_courses.studentid` = `student.studentid`
AND
`student.instID` = 13
AND
`enrolled_courses.courseid` = '13I01C' ;
Now I need to implement this Inner join query in CourseRepository (or enrolledstudent repo)
How to achieve this ?
Please guide me
If we use hibernate mapping in EnrolledCourses entity like
#Entity
public class EnrolledCourses {
#Id
String enrolledId;
#ManyToOne
Student student;
#ManyToOne
Course course;
Date joined;
getters and setters()...
}
from the above mappings without using any SQL queries, you can retrieve all student who comes under a particular course
By using the method in the interface
#Repository
public interface EnrolledRepository extends CrudRepository<EnrolledCourses,String> {
List<EnrolledCourses> findByCourse_CourseId(String courseId);
}
if we have some relations between the entities we can easily retrieve all the fields using Jpa.

How to search through array in Spring Boot CrudRepository

Say, I have the following entity class:
Person.java
#Entity
public class Person {
#Id
private String name;
private String[] cars;
// Constructor, getters and setters
}
And the repository:
PersonRepository.java
public interface PersonRepository extends CrudRepository<Person, String> {
// this is unclear!
List<Person> getAllByCars...(String car)
}
Is there a method that returns all persons, whose car array contains one given car (the String parameter above)?
For me, it seems that all supported JPA keywords can only deal with single elements, but not with arrays.
Thanks for help!
Ideally, You should declare cars as a separate Entity like this
#Entity
public class Person {
#Id
private String name;
private List<Car> cars;
// Constructor, getters and setters
}
If not you should change Array to List at the least.
change
private String[] cars;
to
#ElementCollection
private List<String> cars;
Then You have to write a Query like this
#Query("select p from Person p WHERE :car in elements(p.cars)")
List<Person> getAllByCars...(#Param("car") String car)
I'm guessing at how you are currently storing the cars information and suggesting a possible solution:
#Entity
public class Car {
#Id
private String name;
#Column
private String person_name;
}
public interface CarRepository extends JpaRepository<Car, String> {
//Result will have all cars with the person_name identifying the Person #Entity
List<Car> findByName(String name);
}

Spring data jpa inheritance - table per class not working

I have an abstract entity.
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
#EntityListeners(AuditingEntityListener.class)
public abstract class AbstractEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
protected long id;
#CreatedBy
protected String createdBy;
#CreatedDate
protected Date creationDate;
#LastModifiedBy
protected String modifiedBy;
#LastModifiedDate
protected Date lastModifiedDate;
}
And 2 concrete implementations of this class:
Class A:
#Entity
#Table(name = "A")
public class A extends AbstractEntity {
#Column(name = "NAME", nullable = false)
private String name;
#Column(name = "PRIORITY", nullable = false)
private int priority;
}
Class B:
#Entity
#Table(name = "B")
public class B extends AbstractEntity {
#Column(name = "PLACE", nullable = false)
private String place;
#Column(name = "DISTANCE", nullable = false)
private int distance;
}
And a common repository interface:
#NoRepositoryBean
public interface IRepository extends Repository<AbstractEntity, Long> {
/**
* Method to query by unique id/PK.
* #param id
* #return Entity with id "id"
*/
#Query("select entity from #{#entityName} as entity where entity.id = ?1")
public AbstractEntity findById(long id);
/**
* Insert method
* #param abstractEntity
* #return modified entity after insertion
*/
public AbstractEntity save(AbstractEntity abstractEntity);
/**
* select all records from the table
* #return list of all entities representing records in the table
*/
#Query("select entity from #{#entityName} as entity")
public List<AbstractEntity> findAll();
/**
* delete record by id
* #param id
*/
public void deleteById(long id);
}
And each class has it's own repository which extends the generic repository:
public interface ARepository extends IRepository {
}
public interface BRepository extends IRepository {
}
When I invoke findAll() on ARespository, I get the records in both ARepository and BRepository. Since, the inheritance type is specified as TABLE_PER_CLASS, I assumed that a findAll() would only pick records from that table. I even added a query to the findAll() method to detect entity type and pick records appropriately, but this doesn't seem to be doing anything. Is there something I'm missing here?
I'm using Hibernate as my underlying persistence framework and am working on HSQLDB.
Thanks,
Aarthi
The typing of your repositories is incorrect change it to.
#NoRepositoryBean
public interface IRepository<Entity extends AbstractEntity> extends Repository<Entity, Long> {
}
public interface ARepository extends IRepository<A> {
}
public interface BRepository extends IRepository<B> {
}

Spring: Method Injection Lookup How to use it?

Can I use Method Injection Lookup -- with a entity class?.I use Spring+JPA+Hibernate. This allow to inject a prototype bean into a singleton bean.Is this also possible with entity beans?A is prototype scoped bean.I want to put A(#Entity) into a class B (ex. DAO) with scope=singleton.Thanks
#Entity
public class A(){
private String name;
private String surname;
...//get and set
}//A
public interface DAO{
public void method();
}//DAO
public class DAOImpl implements DAO{
private A object_a;
public void method(){
//In this method I use everytime a new istance of A
}//method
}//DAOImpl
You can use #Embedded to include your sub bean, and use in your sql.
#Entity
public class User(){
private String name;
#Embedded
private Address address;
#Bean(scope=DefaultScopes.PROTOTYPE)
public User() {
}
...//get and set
}
#Entity
public class Address(){
private String name;
...//get and set
}
public interface UserRepository extends JpaRepository<User, Long> {
#Query(value = "select u from users u where u.address.name = :addressName")
List<Blog> findUserByAddress(#Param("addressName") String addressName);
}

Spring MongoRepository query adding _class field to queries

I have a domain class called User. It uses an object of MyUserId as the Id
#Document(collection = "users")
public class User implements Serializable {
#Property
#Id
private MyUserId id;
#Version
private Integer version;
private String firstName;
// Setters, getters
}
The MyUserId class:
public class MyUserId implements Serializable{
#Property
private String userId;
#Property
private String sampleId;
// setters, getters
}
Inside my Mongo, documents are getting stored as {_id:{userId:....., sampleId:....}, <more fields here>}
My userRepository is like this:
public interface UserRepository extends MongoRepository<User, MyUserId> {
#Query("{'_id': {$in: ?0}}")
List<User> findByUserIds(Collection<MyUserId> userIds);
}
When I'm querying my userRepository, The query is being fired as:
{_id: {$in: [ {_class:"com.sampleuser.MyUserId", userId:"....", sampleId:"...."}, {_class:"com.sampleuser.MyUserId", userId:"....", sampleId:"...."}]}}
It's obvious that it's adding the _class field while querying, but not while storing. Can someone throw some light at how to fix this? It's causing all my queries to fail. Thank you!
There actually exists an issue when using #Query whith complex id types. I'd suggest to use a custom repository implementation until DATAMONGO-1078 is resolved.
Within the custom implementation you could use MongoTemplate to execute the query somehow like this
#Override
public List<User> findByUserIds(Collection<MyUserId> userIds) {
return template.find(query(where("id").in(userIds)), User.class);
}

Resources