Is there an option to add different collection in edge using arangodb-spring-data - spring-boot

In arangoDB, we can create an edge in which we can set #from and #to to different collection since these are all json data. In ArangoDB-Spring-Data library we can create an edge and we have to provide type to #from and #to. I want to add relation between different collection using same edge. For example-
I have a class EntitywithKey-
public class EntityWithKey {
#Id
protected String id;
}
I have 2 classes which extends EntityWIthKey
#Document("actors")
#HashIndex(fields = { "name", "surname" }, unique = true)
public class Actor extends EntityWithKey{
private String name;
private String surname;
}
#Document("characters")
#HashIndex(fields = { "name", "surname" }, unique = true)
public class Character extends EntityWithKey {
private String name;
private String surname;
}
i want to create an edge like below-
#Edge
public class ChildOf {
#Id
private String id;
#From
private EntityWithKey child;
#To
private EntityWithKey parent;
}
So that i can add relationship between Actor-Actor, Actor-Character, Character-Character and Character-Actor.
But i am seeing an error
nested exception is org.springframework.data.mapping.PropertyReferenceException: No property name found for type EntityWithKey!
Is there any option with this library to do that?

I have fixed the issue. The edge will have to be created with java generics-
#Edge
public class ChildOf<T1,T2> {
#Id
private String id;
#From
private T1 child;
#To
private T2 parent;
}
Now i can add any two connectors in single edge relationship

Related

how to return relationship in spring data neo4j

Here's nodeEntity
#Data
#NodeEntity
public class Resource {
#Id
#GeneratedValue
private Long id;
#Property("name")
private String name;
private String code;
#Property("parent_code")
private String parentCode;
private String label;
private Neo4jRelationship relationship;
}
And here's relationship between nodes
#Data
#RelationshipEntity
public class Neo4jRelationship {
#Id
private Long id;
#StartNode
private Resource startNode;
#EndNode
private Resource endNode;
}
I want to query all the relationship satify some condition,
#Query("match p = (a : category_first {name: $name})-[*1..2]-() return p")
List<Neo4jRelationship> getFistCatNode(#Param("name") String name);
but the query return am empty list.
However, if I change the return type to org.neo4j.ogm.model.Result, the query can return normally.
I'm confused why the first way dosen't work. Any help will be grateful

Hibernate Fetch #Formula annotated fields on demand

I have a entity (declared with 2 way)(some not influencing code part are ommited for readability)
Entity version 1.
#Entity
public class Article {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#Formula("(SELECT COUNT(w.id) FROM stock s LEFT JOIN warehouse w ON s.id=w.stock_id WHERE s.article_id = id)")
private int variants;
public int getVariants() {
return variants;
}
}
Entity version 2.
#Entity
public class Article {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#Transient
private int variants;
#Access(AccessType.PROPERTY)
#Formula("(SELECT COUNT(w.id) FROM stock s LEFT JOIN warehouse w ON s.id=w.stock_id WHERE s.article_id = id)")
public int getVariants() {
return variants;
}
}
respective DTO and ArticleMapper - MapStruct
#JsonIgnoreProperties(ignoreUnknown = true)
public class ArticleDTOCommon {
private Long id;
private String name;
}
#JsonIgnoreProperties(ignoreUnknown = true)
public class ArticleDTO {
private Long id;
private String name;
private int variants;
}
#Mapper(componentModel = "spring", uses = {})
public interface ArticleMapper{
ArticleDTO toDto(Article article);
ArticleDTOCommon toDtoCommon(Article article);
}
I have a #Service layer on which how i know Hibernate creates it's proxy(for defining which field is fetch or not fetch) and transactions are occurs.
#Service
#Transactional
public class ArticleService {
#Transactional(readOnly = true)
public List<ArticleDTO> findAll() {
return articleRepository.findAll()
stream().map(articleMapper::toDto).collect(Collectors.toList());
}
#Transactional(readOnly = true)
public List<ArticleDTO> findAllCommon() {
return articleRepository.findAll()
stream().map(articleMapper::toDtoCommon).collect(Collectors.toList());
}
}
It works fine with fetching Related entity but
Problem is (fetching #Formula annotated field) when I am looking executed query on log it fetchs all time variants #Formula annotated query not depending on respective DTO.
But it must be ignored on toDtoCommon - i.e. It must not fetch variants field -> because when mapping Article to ArticleDtoCommon it not uses getVariant() field of Article. I have tried multiple ways as mentioned above.
I can solve it with writing native query(for findAllCommon() method) and map respectivelly with other way... But I want to know that how we can solve it with ORM way and where is problem.
Manupulating #Access type is not helping too.
Thanks is advance.

mongoDB find in query

I have two entities, course and subject as follows,
#Document(collection = "course")
public class Course implements Serializable {
{
...........
#Field("course_name")
private String courseName;
#Field("subjectIds")
private List<String> subjectIds;
...
}
#Document(collection = "subject")
public class Subject implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String id;
#Field("subject_name")
private String subjectName;
...................
}
here "Course" contains the list of Ids of Subject.
So , I have a subject Id say ("59ce80a4a2e7f329eccac601"), I need to find all the courses where this subject id will be present in the list of subjectIds property of Course.
Is there any way I can write this in query.
I am using mongorepository of spring
MongoDB native query:
db.course.find({subjectIds: { $elemMatch: { $eq: "59ce80a4a2e7f329eccac601"}}})
A corresponding Spring Data MongoDB Query:
#Query("{'subjectIds': {\$elemMatch: {\$eq: ?0}}}")

Spring/JPA: composite Key find returns empty elements [{}]

I have build my data model using JPA and am using Hibernate's EntityManager to access the data. I am using this configuration for other classes and have had no problems.
The issue is that I created an entity with a composite primary key (the two keys are foreign keys) , adding elements works perfectly I checked it in database but I am not able to retrieve the populated row from database.
For example if I query "FROM Referentiel" to return a list of all referentiels in the table, I get this [{},{}] my list.size() has the proper number of elements (2), but the elements are null.
The entity:
#Entity
#Table(name = "Et_referentiel")
public class Referentiel implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#ManyToOne
#JoinColumn(name = "id_projet")
private Projet projet;
#Id
#ManyToOne
#JoinColumn(name = "id_ressource")
private Ressource ressource;
#Column(name = "unite", nullable = false)
private String unite;
}
here is my controller getList method:
#PostMapping(value = "/list", consumes = { MediaType.APPLICATION_JSON_UTF8_VALUE })
public List<Referentiel> listReferentiel(#RequestBody Long idProjet) {
List<Referentiel> referentiel = referentielService.listReferentiel(idProjet);
return referentiel;
}
and here is my dao methods:
#Autowired
private EntityManager em;
#Override
public void ajouterReferentiel(Referentiel ref) {
em.persist(ref);
em.flush();
}
#SuppressWarnings("unchecked")
#Override
public List<Referentiel> listReferentiel(Long idProjet) {
Query query = em.createQuery("Select r from Referentiel r where r.projet.idProjet=:arg1");
query.setParameter("arg1", idProjet);
em.flush();
List<Referentiel> resultList = query.getResultList();
return resultList;
}
Any help is greatly appreciated.
Try creating a class representing your composite key:
public class ReferentielId implements Serializable {
private static final long serialVersionUID = 0L;
private Long projet; // Same type than idProjet, same name than inside Referentiel
private Long ressource; // Same type than idRessource (I guess), same name than inside Referentiel
// Constructors, getters, setters...
}
And assign it to your entity having that composite key.
#Entity
#IdClass(ReferentielId.class) // <- here
#Table(name = "Et_referentiel")
public class Referentiel implements Serializable {
// ...
}
Notice that it is required to have a class representing your composite keys, even if that does not help in your problem.

Spring Data Couchbase: How to rename fields from nested POJOs?

Doc says that the #Field annotation can be used to rename a field in an entity. What about fields from nested POJOs that are technically not entities themselves? Consider the following hypothetical example.
#Document
public class Person {
#Id
private String ssn;
#Field
private String name;
#Field
private Address address;
static class Address {
// how to rename this field to line1?
private String street;
}
}
To answer your question specifically, you can use #Field("line1") for street in Address.
I have something like this in my project and it works fine (see descriptions)
Class 1
#Document
#JsonInclude(JsonInclude.Include.NON_NULL)
public class HotelInfo {
#Field("hotel_type") #JsonProperty("hotel_type")
public String hotelType;
#Field #JsonProperty("images")
public List<Image> images = new ArrayList<Image>();
#Field #JsonProperty("regions")
public List<String> regions = new ArrayList<String>();
#Field #JsonProperty("themes")
public List<String> themes = new ArrayList<String>();
#Field #JsonProperty("facilities")
public List<String> facilities;
#Field #JsonProperty("descriptions")
public Descriptions descriptions;
}
Class 2
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Descriptions {
#Field("hotel_information") #JsonProperty("hotel_information")
public String hotelInformation;
}

Resources