I'm having trouble understanding how the #RelationshipEntity works. I've tried following examples, but even though I think I'm following the same pattern as the example, I end up witha stackoverflow, because the Relationship Entity grabs the NodeEntity, which has the RelationshipEntity, and on and on...
My model is:
(:Vendor)-[:BELONGS_TO {active: true, sinceDate: date}]->(:Store)
So my two nodes are Vendor and Store:
#NodeEntity
#Data
public class Vendor {
#GraphId
private Long id;
private Long vendorId;
private String name;
private String address;
#Relationship(type = "OWNS")
private Collection<Inventory> inventory;
#Relationship(type = "BELONGS_TO")
private Collection<Store> store;
}
#NodeEntity
#Data
public class Store {
#GraphId
private Long id;
private Long storeId;
private String name;
private String address;
private String email;
#Relationship(type = "BELONGS_TO", direction = Relationship.INCOMING)
private List<StoreParticipant> storeParticipant;
}
And my RelationshipEntity:
#RelationshipEntity(type = "BELONGS_TO")
#Data
public class StoreParticipant {
#GraphId
private Long id;
#StartNode
private Vendor vendor;
#EndNode
private Store store;
private int count;
private double price;
private boolean negotiable;
private boolean active;
}
I based this off of the Movie example which had (:Person)-[:ACTED_IN]->(:MOVIE) and the acted_in relationship was ROLE
This is happening when I call the repository method findByVendorId
#Repository
public interface VendorRepository extends GraphRepository<Vendor> {
List<Vendor> findByVendorId(Long vendorId);
}
If you're referencing this from both ends, you need to reference the relationship entity, not the node entity directly.
Store looks fine but Vendor contains
#Relationship(type = "BELONGS_TO")
private Collection<Store> store;
when it should be
#Relationship(type = "BELONGS_TO")
private Collection<StoreParticipant> store;
Related
My entities are as follows
Office
#Entity
public class Office {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private int latitude;
private int longitude;
private String buildingName;
// getters and setters omitted for brevity
}
Point - which is an EmbeddedId
#Embeddable
public class Point implements Serializable {
private int latitude;
private int longitude;
// getters and setters omitted for brevity
}
Location
#Entity
public class Location {
#EmbeddedId
private Point point;
private String country;
#OneToOne // How to add a OneToOne Mapping
private Office office;
// getters and setters omitted for brevity
}
Question:
I want to add a one-to-one mapping between the Office and the Location entity.
What I've tried:
I added the following annotations along with #OneToOne mapping in the Location entity
#JoinColumn(name = "latitude", referencedColumnName = "latitude")
#JoinColumn(name = "longitude", referencedColumnName = "longitude")
but I got the following error
Provided id of the wrong type for class com.example.demo.entity.employee.o2m_cpk.Office. Expected: class java.lang.Integer, got class com.example.demo.entity.employee.o2m_cpk.Point
Use the following mappings:
#Entity
public class Office {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#OneToOne(mappedBy = "office")
private Location location;
private String buildingName;
}
#Embeddable
public class Point implements Serializable {
private int latitude;
private int longitude;
}
#Entity
public class Location {
#EmbeddedId
private Point point;
private String country;
#OneToOne
private Office office;
}
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
I'm trying to update my user entity and I have an error that comes to mind:
ERROR: A NULL value violates the NOT NULL constraint of the "id" column Detail: The failed row contains (null, 1, 1)
The problem surely stems from my relationship between user and profile which is n-n
public class Utilisateur implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private Integer id;
private Integer fixe;
private Boolean deleted;
private Boolean actif;
private String email;
private Integer mobile;
private String motDePasse;
private String nom;
private String prenom;
#ManyToMany
private List<Profil> profils = new ArrayList<Profil>();
public Utilisateur() {
}
}
public class Profil implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private Integer id;
private String codeProfil;
private String libelleProfil;
#JsonManagedReference
#ManyToMany
private List<MenuAction> menuActions = new ArrayList<MenuAction>();
public Profil() {
}
}
How you generate value for your id?
Seems you need some way to generate value for you ID.
For example, use #GeneratedValue, like:
#GeneratedValue(strategy = IDENTITY)
I want to create an entity X with atributes.
Everything is right except the attribute "permissions" :
public class X implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long idNotateur;
#NotEmpty
private String nomNotateur;
#NotEmpty
private String prenomNotateur;
#NotEmpty
private String fonctionNotateur;
#NotEmpty
private String userNotateur;
#NotEmpty
private String passNotateur;
#ManyToOne
#JoinColumn(name="id_poste")
private Poste poste;
#ManyToOne
#JoinColumn(name="id_dir")
private Direction direction;
#OneToMany(mappedBy="notateur")
private Collection<Employe> Employes;
private Collection<Long> permissions;
getters & setters ...
public Collection<Long> getPermissions() {
return permissions;
}
public void setPermissions(Collection<Long> permissions) {
this.permissions = permissions;
}
}
Then I came across the following error: Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Collection, at table: X, for columns: [org.hibernate.mapping.Column(permissions)]
So how to solve it?
I'm using Spring MVC Hibenate
Can you tell me, why the record is posted twice in the database. I think. this happens because I use save() method. But shouldn't I save the master-entity and dependent-entity separately?
Controller method:
#RequestMapping(value = "/addComment/{topicId}", method = RequestMethod.POST)
public String saveComment(#PathVariable int topicId, #ModelAttribute("newComment")Comment comment, BindingResult result, Model model){
Topic commentedTopic = topicService.findTopicByID(topicId);
commentedTopic.addComment(comment);
// TODO: Add a validator here
if (!comment.isValid() ){
return "//";
}
// Go to the "Show topic" page
commentService.saveComment(comment);
return "redirect:../details/" + topicService.saveTopic(commentedTopic);
}
Services:
#Service
#Transactional
public class CommentService {
#Autowired
private CommentRepository commentRepository;
public int saveComment(Comment comment){
return commentRepository.save(comment).getId();
}
}
#Service
#Transactional
public class TopicService {
#Autowired
private TopicRepository topicRepository;
public int saveTopic(Topic topic){
return topicRepository.save(topic).getId();
}
}
Model:
#Entity
#Table(name = "T_TOPIC")
public class Topic {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#ManyToOne
#JoinColumn(name="USER_ID")
private User author;
#Enumerated(EnumType.STRING)
private Tag topicTag;
private String name;
private String text;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "topic", cascade = CascadeType.ALL)
private Collection<Comment> comments = new LinkedHashSet<Comment>();
}
#Entity
#Table(name = "T_COMMENT")
public class Comment
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#ManyToOne
#JoinColumn(name="TOPIC_ID")
private Topic topic;
#ManyToOne
#JoinColumn(name="USER_ID")
private User author;
private String text;
private Date creationDate;
}
In this concrete case, you do not need to save the master and the client.
Saving the master or the client would be enough (with this concrete mapping)
But I think the main problem is that you do not have a good equals method in your Comment so your ORM Provider think that there are two different comments, and therefore store them twice.