How to change or remove target of object relationship in spring data neo4j? - kotlin

In spring data neo4j I have simple one-to-many relationship: (:User)-[:EMPLOYEE_OF]->(:Company). User can be employee of only one company. Here are my entities:
class User(#Relationship(type = "EMPLOYEE_OF") var company: Company? = null, /* ids etc */)
class Company(/* ids etc */)
When I want to change target of that relationship or remove it neo4j keeps adding new relationships instead of replacing it.
val user = userRepository.findByName("user1")
val company = companyRepository.findByName("company1")
user.company = company
userRepository.save(user)
// 2nd case
user.company = null
userRepository.save(user)
In both cases, relationships are only added, never removed.
Is there a proper way to do it?

You have to put the load / find and the save in a transaction. The best way in a Spring project to do this is to extract the logic into a service layer method of your application and mark it as #Transactional.
Within this transaction, Spring Data Neo4j / Neo4j-OGM can track the changes that happen on the node and change or remove the relationships.

Related

What is the best way to get all linked instances of a models in Django?

I am trying to create a messaging system in Django, and I came across an issue: How could I efficiently find all messages linked in a thread?
Let's imagine I have two models:
class Conversation(models.Model):
sender = models.ForeignKey(User)
receiver = models.ForeignKey(User)
first_message = models.OneToOneField(Message)
last_message = models.OneToOneField(Message)
class Message(models.Model):
previous = models.OneToOneField(Message)
content = models.TextField()
(code not tested, I'm sure it wouldn't work as is)
Since it is designed as a simple linked list, is it the only way to traverse it recursively?
Should I try to just get the previous of the previous until I find the first, or is there a way to query all of them more efficiently?
I use Rest Framework serializer with depth. So If you have serializer with Depth value to 3. I will fetch the full model of whatever the foreign key available until three parents.
https://www.django-rest-framework.org/api-guide/serializers/#specifying-nested-serialization
class AppliedSerializer(serializers.ModelSerializer):
class Meta:
model = Applied
fields = ("__all__")
depth = 3

find nodes with a specific child association

I am looking for a query (lucene, fts-alfresco or ...) to return all the document which have a specific child association (that is not null).
Some context:
Documents of type abc:document have a child-association abc:linkedDocument.
Not all document have an other document linked to them, some have none some have one or multiple.
I need a fast and easy way to get an overview of all the documents that do have at least one document linked to them.
Currently I have a webscript that does what I need, but prefer not to have tons of webscripts which are not business related.
code:
SearchParameters sp = new SearchParameters();
String query = "TYPE:\"abc:document\"";
StoreRef store = StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
sp.addStore(store);
sp.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO);
sp.setQuery(query);
ResultSet rs = services.getSearchService().query(sp);
List<NodeRef> nodeRefs = rs.getNodeRefs();
for (NodeRef ref : nodeRefs) {
List<ChildAssociationRef> refs = services.getNodeService().getChildAssocs(ref);
for(ChildAssociationRef chref : refs){
if(chref.getQName().equals(AbcModel.ASSOC_LINKED_DOC)){
logger.debug("Document with linked doc: {}", ref);
break;
}
}
}
Associations aren't query-able so you'll have to do what you are doing, which is essentially checking every node in a result set for the presence of a desired association.
The only improvement I can suggest is that you can ask for the child associations of a specific type which would prevent you from having to check the type of every child association, see How to get all Child associations with a specific Association Type Alfresco (Java)

Managing relationships in Laravel, adhering to the repository pattern

While creating an app in Laravel 4 after reading T. Otwell's book on good design patterns in Laravel I found myself creating repositories for every table on the application.
I ended up with the following table structure:
Students: id, name
Courses: id, name, teacher_id
Teachers: id, name
Assignments: id, name, course_id
Scores (acts as a pivot between students and assignments): student_id, assignment_id, scores
I have repository classes with find, create, update and delete methods for all of these tables. Each repository has an Eloquent model which interacts with the database. Relationships are defined in the model per Laravel's documentation: http://laravel.com/docs/eloquent#relationships.
When creating a new course, all I do is calling the create method on the Course Repository. That course has assignments, so when creating one, I also want to create an entry in the score's table for each student in the course. I do this through the Assignment Repository. This implies the assignment repository communicates with two Eloquent models, with the Assignment and Student model.
My question is: as this app will probably grow in size and more relationships will be introduced, is it good practice to communicate with different Eloquent models in repositories or should this be done using other repositories instead (I mean calling other repositories from the Assignment repository) or should it be done in the Eloquent models all together?
Also, is it good practice to use the scores table as a pivot between assignments and students or should it be done somewhere else?
I am finishing up a large project using Laravel 4 and had to answer all of the questions you are asking right now. After reading all of the available Laravel books over at Leanpub, and tons of Googling, I came up with the following structure.
One Eloquent Model class per datable table
One Repository class per Eloquent Model
A Service class that may communicate between multiple Repository classes.
So let's say I'm building a movie database. I would have at least the following following Eloquent Model classes:
Movie
Studio
Director
Actor
Review
A repository class would encapsulate each Eloquent Model class and be responsible for CRUD operations on the database. The repository classes might look like this:
MovieRepository
StudioRepository
DirectorRepository
ActorRepository
ReviewRepository
Each repository class would extend a BaseRepository class which implements the following interface:
interface BaseRepositoryInterface
{
public function errors();
public function all(array $related = null);
public function get($id, array $related = null);
public function getWhere($column, $value, array $related = null);
public function getRecent($limit, array $related = null);
public function create(array $data);
public function update(array $data);
public function delete($id);
public function deleteWhere($column, $value);
}
A Service class is used to glue multiple repositories together and contains the real "business logic" of the application. Controllers only communicate with Service classes for Create, Update and Delete actions.
So when I want to create a new Movie record in the database, my MovieController class might have the following methods:
public function __construct(MovieRepositoryInterface $movieRepository, MovieServiceInterface $movieService)
{
$this->movieRepository = $movieRepository;
$this->movieService = $movieService;
}
public function postCreate()
{
if( ! $this->movieService->create(Input::all()))
{
return Redirect::back()->withErrors($this->movieService->errors())->withInput();
}
// New movie was saved successfully. Do whatever you need to do here.
}
It's up to you to determine how you POST data to your controllers, but let's say the data returned by Input::all() in the postCreate() method looks something like this:
$data = array(
'movie' => array(
'title' => 'Iron Eagle',
'year' => '1986',
'synopsis' => 'When Doug\'s father, an Air Force Pilot, is shot down by MiGs belonging to a radical Middle Eastern state, no one seems able to get him out. Doug finds Chappy, an Air Force Colonel who is intrigued by the idea of sending in two fighters piloted by himself and Doug to rescue Doug\'s father after bombing the MiG base.'
),
'actors' => array(
0 => 'Louis Gossett Jr.',
1 => 'Jason Gedrick',
2 => 'Larry B. Scott'
),
'director' => 'Sidney J. Furie',
'studio' => 'TriStar Pictures'
)
Since the MovieRepository shouldn't know how to create Actor, Director or Studio records in the database, we'll use our MovieService class, which might look something like this:
public function __construct(MovieRepositoryInterface $movieRepository, ActorRepositoryInterface $actorRepository, DirectorRepositoryInterface $directorRepository, StudioRepositoryInterface $studioRepository)
{
$this->movieRepository = $movieRepository;
$this->actorRepository = $actorRepository;
$this->directorRepository = $directorRepository;
$this->studioRepository = $studioRepository;
}
public function create(array $input)
{
$movieData = $input['movie'];
$actorsData = $input['actors'];
$directorData = $input['director'];
$studioData = $input['studio'];
// In a more complete example you would probably want to implement database transactions and perform input validation using the Laravel Validator class here.
// Create the new movie record
$movie = $this->movieRepository->create($movieData);
// Create the new actor records and associate them with the movie record
foreach($actors as $actor)
{
$actorModel = $this->actorRepository->create($actor);
$movie->actors()->save($actorModel);
}
// Create the director record and associate it with the movie record
$director = $this->directorRepository->create($directorData);
$director->movies()->associate($movie);
// Create the studio record and associate it with the movie record
$studio = $this->studioRepository->create($studioData);
$studio->movies()->associate($movie);
// Assume everything worked. In the real world you'll need to implement checks.
return true;
}
So what we're left with is a nice, sensible separation of concerns. Repositories are only aware of the Eloquent model they insert and retrieve from the database. Controllers don't care about repositories, they just hand off the data they collect from the user and pass it to the appropriate service. The service doesn't care how the data it receives is saved to the database, it just hands off the relevant data it was given by the controller to the appropriate repositories.
Keep in mind you're asking for opinions :D
Here's mine:
TL;DR: Yes, that's fine.
You're doing fine!
I do exactly what you are doing often and find it works great.
I often, however, organize repositories around business logic instead of having a repo-per-table. This is useful as it's a point of view centered around how your application should solve your "business problem".
A Course is a "entity", with attributes (title, id, etc) and even other entities (Assignments, which have their own attributes and possibly entities).
Your "Course" repository should be able to return a Course and the Courses' attributes/Assignments (including Assignment).
You can accomplish that with Eloquent, luckily.
(I often end up with a repository per table, but some repositories are used much more than others, and so have many more methods. Your "courses" repository may be much more full-featured than your Assignments repository, for instance, if your application centers more around Courses and less about a Courses' collection of Assignments).
The tricky part
I often use repositories inside of my repositories in order to do some database actions.
Any repository which implements Eloquent in order to handle data will likely return Eloquent models. In that light, it's fine if your Course model uses built-in relationships in order to retrieve or save Assignments (or any other use case). Our "implementation" is built around Eloquent.
From a practical point of view, this makes sense. We're unlikely to change data sources to something Eloquent can't handle (to a non-sql data source).
ORMS
The trickiest part of this setup, for me at least, is determing if Eloquent is actually helping or harming us. ORMs are a tricky subject, because while they help us greatly from a practical point of view, they also couple your "business logic entities" code with the code doing the data retrieval.
This sort of muddles up whether your repository's responsibility is actually for handling data or handling the retrieval / update of entities (business domain entities).
Furthermore, they act as the very objects you pass to your views. If you later have to get away from using Eloquent models in a repository, you'll need to make sure the variables passed to your views behave in the same way or have the same methods available, otherwise changing your data sources will roll into changing your views, and you've (partially) lost the purpose of abstracting your logic out to repositories in the first place - the maintainability of your project goes down as.
Anyway, these are somewhat incomplete thoughts. They are, as stated, merely my opinion, which happens to be the result of reading Domain Driven Design and watching videos like "uncle bob's" keynote at Ruby Midwest within the last year.
I like to think of it in terms of what my code is doing and what it is responsible for, rather than "right or wrong". This is how I break apart my responsibilities:
Controllers are the HTTP layer and route requests through to the underlying apis (aka, it controls the flow)
Models represent the database schema, and tell the application what the data looks like, what relationships it may have, as well as any global attributes that may be necessary (such as a name method for returning a concatenated first and last name)
Repositories represent the more complex queries and interactions with the models (I don't do any queries on model methods).
Search engines - classes that help me build complex search queries.
With this in mind, it makes sense every time to use a repository (whether you create interfaces.etc. is a whole other topic). I like this approach, because it means I know exactly where to go when I'm needing to do certain work.
I also tend to build a base repository, usually an abstract class which defines the main defaults - basically CRUD operations, and then each child can just extend and add methods as necessary, or overload the defaults. Injecting your model also helps this pattern to be quite robust.
Think of Repositories as a consistent filing cabinet of your data (not just your ORMs). The idea is that you want to grab data in a consistent simple to use API.
If you find yourself just doing Model::all(), Model::find(), Model::create() you probably won't benefit much from abstracting away a repository. On the other hand, if you want to do a bit more business logic to your queries or actions, you may want to create a repository to make an easier to use API for dealing with data.
I think you were asking if a repository would be the best way to deal with some of the more verbose syntax required to connect related models. Depending on the situation, there are a few things I may do:
Hanging a new child model off of a parent model (one-one or one-many), I would add a method to the child repository something like createWithParent($attributes, $parentModelInstance) and this would just add the $parentModelInstance->id into the parent_id field of the attributes and call create.
Attaching a many-many relationship, I actually create functions on the models so that I can run $instance->attachChild($childInstance). Note that this requires existing elements on both side.
Creating related models in one run, I create something that I call a Gateway (it may be a bit off from Fowler's definitions). Way I can call $gateway->createParentAndChild($parentAttributes, $childAttributes) instead of a bunch of logic that may change or that would complicate the logic that I have in a controller or command.

nHibernate Proxy Load using Natural Key

How would I use nHibernate,configured by fluent nhibernate if it makes any difference, to load an entity using natural/alternate key in some cases, rather than the primary key when using the Load method on an ISession.
I still need the functionality to allow me to do both, and in the majority of cases, the entity will be loaded via the PKey, but in some cases (where an external system is involved), I need to select the record using the natural key.
I'd like to keep the performance benefit Load allows, rather than do a query etc.
// Current
int countryID = 1; // from normal input source
Address a = new Address();
a.Country = session.Load<Country>(countryID);
session.SaveOrUpdate(a);
// Required
string countryCode = "usa"; // from external input source
Address a2 = new Address();
a2.Country = session.LoadViaNatualKeySomehow<Country>(c=> c.Code, countryCode); // :)
session.SaveOrUpdate(a2);
AFAIK, it is not possible. As you can see in Ayendes post, there is a query syntax for criteria, the only natural ID in the whole NHibernate API as far as I know. This query translates into a "normal" query, except of the second level cache handling as described in this post.
It would be nice if it wouldn't at least flush the session.
one simple performance enhancement you can do is turning off auto flush before querying by the (immutable!) natural ID:
session.FlushMode = FlushMode.Never;
session.CreateQuery(...by natural id ...);
session.FlushMode = FlushMode.Auto;
This can make a big difference, but does of course not compete to Load.
The reason why it doesn't exist is most probably the fact the entities in the session are all identified by the id.
If you had it:
var entity1 = session.Load<Entit>(id);
// does not exist
var entity2 = session.LoadByNaturalKey(natural id);
How could NH determine that the id and the natural id are identifying the same object, without loading them from the database? The whole session cache gets into trouble.

How to display only specific columns of a table in entity framework?

how to display the some specific columns of table instead of whole table in entity framework.
using (DataEntities cxt = new DataEntities())
{
notes note = cxt.notes.Where(no => no.id == accID).SingleOrDefault();
return notes;
}
For this purpose, I would suggest you to make use of ViewModel like following :-
notes note = cxt.notes.SingleOrDefault(no => no.id == accID);
var model = new YourViewModel // Your viewModel class
{
ID = note.ID,
PropertyOne = note.PropertyOne, // your ViewModel Property
PropertyTwo = note.PropertyTwo
};
You can do this with QueryView.
This implies editing your model directly in XML as there is no designer support for this, but you will get an independant entity with less fields than the original one.
Advantages:
You can then query data base for this truncated entity directly (you will get only fields you need from the data base - no need to get whole entity from DB and trancate it in code)
It is good in scenarios where you want to send this truncated entity to the
client
with WCF to minimize traffic (e.g. when building big lists on client
that basically need only name and ID and no other entity specific
information).
Disadvantages:
This QueryView-based entity is read only. To make it writeable you will have to add r/w functionality yourself