Spring JPA relations - spring

So I have a project that is pretty much one of those apps that keeps track of the movies and TV shows you watch. I have a MovieDAO, TvshowDAO, CommentDAO, RatingDAO, PersonalityDAO, and a UserDAO.
It is supposed to function such that a user can make a comment and give ratings, so both RatingDAO and CommentDAO have a relationship to the user. Now, each comment (and each rating) is on a movie OR a TV show OR a personality.
What's the best way to map this? Put three relations in the comment and rating to each individual one, or is it possible to put something like a private Object target and map it to a movie OR a TV show OR a personality?
I'm quite stuck on how to do this. What's the best way?
EDIT: relations as in #ManyToOne personality, #ManyToOne movie, and same in TV show and only fill one

Related

Creating multiple models/controllers

I'm still learning Codeigniter/PHP/Database/SQL.
Whenever i encounter new problems, i usually learn something to solve them that may/may not apply to my previous methods.
If they do apply to previous methods or if i make changes to my database design, i usually have to edit/update my CRUD methods relevant to the tables changed.
The problem lay there, since i write my methods as i need them and i don't follow any plan so they're all over the place.
It's not that its not solveable but its very hassle and it just saps away any anticipation i had towards improving my codes then i end up just doing other stuff(procrastinating), its a very vicious cycle, whenever i try to get into it, i end up procrastinating then days pass by then weeks.
I also want to implement thin controller/fat model idea ive read online. Up to now, this is also a part of the problem. I'm trying to solve them all right now but i have a question/doubt before i can truly do it.
I separated my controller into two. 1. needs authentication 2. no authentication.
For now, i have my main controller with methods that needs a user logged in.
for example, user/story dashboard, submitting stories. etc.
The other one is my pages controller, i put there the methods that don't need any user authentication. Like viewing homepage, viewing story profile, reading a chapter, viewing user profile. etc.
In my models, i have separated them into two. account_model and story_model. Any method related to account like registration,logging in etc. and story like publishing story,fetching story data, etc.
My problem with that is that there are some methods that fall into a gray area. or some methods that i would like to group but get separated.
For example: I have a review system(my previous question), users can review other users(author) who have published their stories, stories and chapters.
In my models, the review_author method would go into account model, the review_story and review_chapter would go into story model.
Is it correct for me to just make a review_model and put them all there?
In line of that thought, can i also make separate models for separate groups of methods for example, Pagination model for any method related to pagination(user/story). dashboard model for any method related to my user/story dashboard.
The essence of my question is that i want to be as efficient as possible(of my level of knowledge) so that whenever i get far into my project i don't lose enthusiasm if i have to make changes because of the headache inducing wall of codes.

Objectify, efficient relationships. Ref<> vs storing id and duplicating fields

I'm having a hard time understanding Objectify entities relationship concepts. Let's say that i have entities User and UsersAction.
class User{
String nick;
}
class UsersAction{
Date actionDate;
}
Now in the frond-end app I want to load many UsersActions and display it, along with corresponding user's nick. I'm familiar with two concepts of dealing with this:
Use Ref<>,
I can put a #Load Ref in UsersAction, so it will create a link between this entites. Later while loading Users Action, Objectify will load proper User.
class User{
String nick;
}
class UsersAction{
#Load Ref<User> user;
Date actionDate;
}
Store Id and duplicate nick in UsersAction:
I can also store User's Id in UsersAction and duplicate User's nick while saving UsersAction.
class User{
String nick;
}
class UsersAction{
Long usersId;
String usersNick;
Date actionDate;
}
When using Ref<>, as far as I understand, Objectify will load all needed UsersActions, then all corresponding Users. When using duplication Objectify will only need to load UsersActions and all data will be there. Now, my question is. Is there a significant difference in performance, between this approaches? Efficiency is my priority but second solution seems ugly and dangerous to me since it causes data duplication and when User changes his nick, I need to update his Actions too.
You're asking whether it is better to denormalize the nickname. It's hard to say without knowing what kinds of queries you plan to run, but generally speaking the answer is probably no. It sounds like premature optimization.
One thing you might consider is making User a #Parent Ref<?> of UserAction. That way the parent will be fetched at the same time as the action in the same bulk get. As long as it fits your required transaction throughput (no more than 1 change per second for the whole User entity group), it should be fine.

Cyclic Dependency when using RelationshipEntity

Let's say, i have an User and a Product.
The user should be able to rate products and a rating can have a lot of properties like for example a number of stars from 1 to 5.
I'd like to have the Product and the User in different Maven modules.
However, Product should know its Owner, so there is a dependency to the module, holding User.
I also would like to have a Rating-Module that contains everything related to ratings.
I constructed the Rating
#RelationshipEntity(type="RATES")
public class Rating{
private Long id;
#StartNode
private User rater;
#EndNode
private Product ratee;
#Property
private RatingProperty property;
//Getter/Setter
}
Where the RatingProperty contains the int representing the 1 to 5 star rating.
Now I understand from the Documentation that I need to have the Rating as an attribute inside some node because SDN4 doesn't accept it otherwise.
Indeed when i did not use it as an attribute and tried save it, i got the id null and not element appeared in the DB.
Since the Rating needs to know both User and Product, I get a cyclic dependency when I try to put the Rating into the User class.
The same when i put it into the Product Class.
As far as I understand at the moment, using a RelationshipEntity seems to not be possible when the Start- and EndNode entities are in different Maven Modules, because the Relationship needs to know both and one of the nodes needs to know the relationship.
This doesn't seem right, so I think I understand something very wrong.
I also tried creating a new NodeEntity inside the Rating-Module just to hold the Rating. This was
#NodeEntity
public class RatingWrapper{
private Long id;
#Relationship(type="RATES)
private Rating rating;
//Getter/Setter
}
but this way i got the same behavior that i did when i didn't use the RelationshipEntity as an attribute somewhere.
Do you see a way to do this better?
A RelationshipEntity represents an edge with in the graph on which you can set and retrieve properties via your domain objects. However, because Neo4j does not support hyper-edges (edges attached to other edges), those properties must be simple Java properties, not other objects in your domain like RatingProperty.
Try replacing RatingProperty with a simple Integer first and see if that solves your problem. If so, you can then use a Custom Converter to convert between the Integer property rating in the graph and your RatingProperty object.
If your domain objects are in different modules this should not cause any problems: just ensure that all of the relevant packages are enumerated in the argument to the SessionFactory constructor:
new SessionFactory("app.module1.domain", "app.module2.domain", ...)
When testing Vinces advice, I changed the progress of creating the relationship. Unitl now, i persisted the startnode, then the endnode and then tried to use a repository extends GraphRepository<Rating> to save the RelationshipEntity. Whenever I did this, i got a rating with id null. When I added the rating as an attribute to the startnode and instead of saving the new relationship, saved the startnode, it worked.
I'm not sure, if this is the proposed way, but I got my relationship, so it works for me.

Interface for viewing demographic information in maps

I am involved in a research project where we try to find correlation between demographics and restaurant types. We want to have an interface where we can apply the demographic information over a map of the city as filters and check how the restaurant types and information changes.
I am lost on what sort of tools to use for this purpose.
Note: I am not sure whether this is the right place to post this question. If there is a specific SO site for this, I will move it there.
There isn't a specific SO site for openstreetmap, but even better there is a https://help.openstreetmap.org/ site which would be an even better place to ask.

Fat Domain Models => Inefficient?

Looking at DDD, we abstract the database into the various models which we operate on and look at it as a repository where our models live. Then we add the Data Layers and the Service/Business layers on top of it. My question is, in doing so, are we creating inefficiencies in data transfer by building fat models?
For example, say we have system that displays an invoice for a customer on the screen.
Thinking of it in terms of OOP, we'd probably end up with an object that looks somewhat like this:
class Invoice {
Customer _customer;
OrderItems _orderitems;
ShippingInfo _shippingInfo;
}
class Customer {
string name;
int customerID;
Address customerAddress;
AccountingInfo accountingInfo;
ShoppingHistory customerHistory;
}
(for the sake of the question/argument,
let's say it was determined that the customer class had to
implement AccountingInfo and ShoppingHistory)
If the invoice solely needs to print the customer name, why would we carry all the other baggage with it? Using the repository type of approach seems like we would be building these complex domain objects which require all these resources (CPU, memory, complex query joins, etc) AND then transferring it over the tubes to the client.
Simply adding a customerName property to the invoice class would be breaking away from abstractions and seems like a horrible practice. On the third hand, half filling an object like the Customer seems like a very bad idea as you could end up creating multiple versions of the same object (e.g. one that has a an Address, but no ShoppingHistory, and one that has AccountingInfo but no Address, etc, etc). What am I missing, or not understanding?
As good object relational mappers can lazy load the relationships, you would therefore pull back the customer for your invoice, but ignore their accounting and shopping history. You could roll your own if you're not using an oject-relational mapper.
Often you can't do this within your client as you'll have crossed your trasaction boundary (ended your database trasaction) and so it is up to your service layer to ensure the right data has been loaded.
Testing the right data is available (and not too much of it) is often good to do in unit tests on a service layer.
You say "it was determined that the customer class had to implement AccountingInfo and ShoppingHistory", so clearly displaying an invoice is NOT the only task that the system performs (how else was it "determined" that customers need those other functionalities otherwise?-).
So you need a table of customers anyway (for those other functionalities) -- and of course your invoice printer needs to get customer data (even just the name) from that one table, the same one that's used by other functionality in the system.
So the "overhead" is purely illusory -- it appears to exist when you look at one functionality in isolation, but doesn't exist at all when you look at the whole system as an integrated whole.

Resources