I have 3 entities EntityA, EntityB and EntityC
EntityA can have many EntityB
EntityB will have one EntityC and a CreatedDate
I want to retrieve all EntityAs with the latest EntityB if one exists and associated EntityC.
I'm really struggling on the LINQ (lambda or otherwise). Can you help?
EntityAs.Select(a=>new EntityA {
EntityBs=a.EntityBs.OrderByDescending(b=>b.CreateDate).Take(1)});
If it is an EF entity, then you might need to include C, like this:
EntityAs
.Include(a=>a.Select(b=>b.EntityC))
.Select(a=>new EntityA {
EntityBs=a.EntityBs.OrderByDescending(b=>b.CreateDate).Take(1)});
Related
Let's say we have two entities, EntityA and EntityB, and those entities are bidirectional. How we should obtain entityB? Does it make sense to add a new method to the repository like findAllByEntityA() or we may use getEntitiesA() getter?
You could add a new spring repo method, or simply use a #Getter annotation, or implement your own getter method.
You could do findAllByEntityA() as a way of fetching EntityB if you expect to have a List<EntityB> returned. On the other hand, I would expect based on the naming convention that getEntitiesA() would be for fetching a List<EntityA> & not for B's.
It really depends on your bi-directional relationship but, basically all of the jpa one-to-one, one-to-many, many-to-one, many-to-many mappings simply boil down to foreign key constraints.
as turbofood already said. There are differet kinds of mappings:
One-to-One mappings. Like a Driver and a Car: One car can only be driven by one Driver and one Driver can only drive one Car.
Many-To-One mappings: Like a father and a child, one Father can have multiple children but one children can only have one father.
Many-To-Many mappings: Like student and teacher. A student can have multiple teachers and one teacher can have multiple students.
For One-To-One-Mappings and for Many-To-One mappings you have exactly one foreign-key. But for Many-To-Many-Mappings you have two foreign-keys that are part of a db-relation-table (that must not have a jpa-entity).
Using JPA/Hibernate we differenciate the endpoints between relations into two kinds: The owning-Side (getter and setter) and the non-owning side (getter and setter).
For many-to-many-relations this is the owning-side:
#OrderBy
#ManyToMany
#JoinTable(name="`STUDENT_TO_TEACHER`", joinColumns = {
#JoinColumn(name="`student_id`", referencedColumnName="`id`", nullable=false),
}, inverseJoinColumns = {
#JoinColumn(name="`teacher_id`", referencedColumnName="`id`", nullable=false)
})
public Set<Student> getStudents() {
return this.students;
}
And the non-owning-side:
#ManyToMany(mappedBy="students")
public Set<Teacher> getTeachers() {
return teachers;
}
Now why owning-side and non-owning side is important:
Student student = ...
Teacher teacher = ...
// a bad example:
student.getTeachers().add(teacher); // STUDENT.TEACHERS IS NOT THE OWNING SIDE
entityManager.persist(student); // THIS IS NOT POSSIBLE!
// a good example
teacher.getStudents().add(student); // good
entityManager.persist(teacher); // possible, teacher have a new student.
There is another rare case of mapping beside this 1-1/n-m/1-n sides the Map<> association. The Map<> association let you use a map as a getter in hibernate. I never used it so I can not elaborate experience in this.
I have an entity Product which have many fields and associations (around 60).
And a table ProductView which has a #ManyToOne(fetch = FetchType.LAZY) association with Product.
Is there a optimal way to retrieve Product object and assign it to ProductView ?
If its used JPA findById(productId) or JPQL/EntityManager selects-> It will retrieve all products fields and associations
Product product = productRepository.findById(productId);
ProductView productView = new ProductView(product);
save(productView);
If its used JPA getOne -> It solves the problem but the Proxy can throw error if Product does not exists. And this error can not be handled because it happens at runtime.
Product product = productRepository.getOne(productId);
ProductView productView = new ProductView(product);
save(productView);
If a DTO is used or Interface which refers to the same Product Table -> We will get just an object with Id field, but a lot more processes will need to be added (Which I am not familiar with)
Delete foreign keys from ProductView table (#ManyToOne -> #Column) and simple assign productIds. But in this way, there will be no logic connection between tables.
ProductView DB
How usually developers avoid this problem ?
I don't understand what the problem is. Just use getOne approach and at the end of your method, use flush which will throw the constraint violation exception that you can handle. This is the way to go.
I have two tables students and subjects. A student can have more than one subject and vice versa. I have two model classes and vave joined using Many to Many relationship in spring boot and JPA.My problem is how I can delete values from my join table. But I can't figure out how I can do delete from join table. For Student and Subject Model I delete comfortably using deleteById() function.This is my code:
#ManyToMany
#JoinTable(
name = "student_subject",
joinColumns = #JoinColumn(name = "student_id"),
inverseJoinColumns = #JoinColumn(name = "subject_id"))
private Set<SubjectModel> subjects;
//and my repository Class
#Repository
public interface SubjectDao extends JpaRepository<SubjectModel, Integer> {}
You have to delete the corresponding objects form both sides of the link, and then save them.
myStudent.getSubjects().remove(mySubject);
mySubject.getStudents().remove(myStudent);
SubjectDao subjectDao = new SubjectDao();
subjectDao.save(mySubject);
Here another examle: Hibernate: delete many-to-many association
You have two table Student and Subject.
And I suppose you want is delete one of the subject from a student.
For that you should let jpa delete the row from subject and student-subject association table. And dont need to user SubjectRepository.
Take a look.
Student firstStudent=studentRepository.findById(1);
Set<SubjectModel> subs=firstStudent.getSubject();
subs.clear();
firstStudent.setSubject(subs);
studentRepository.save(firstStudent); // this method will delete the row from assiciation table as well as the subject table.
I would like to modify the spring's rest tutorial. Link here
The tutorial has two entity: User and bookmark ( many bookmark can belong to one user. )
I would like to modify it a bit. I would like to create a user, question, answer entity - a user can have many questions, and a question can have many answers.
Is this possible?
How should the entity definition look like for the question entity?
The logic would be that a user could create quizzes. The quiz can contain questions, and those questions may have possible answers.
Any ideas how should the entities look like?
I would appreciate every idea.
Is it possible to use one-to-many and many-to-one in the same entity?
I assume your question is, can "questions entity" have one-to-many relationship with Answers entity and many-to-one relationship with User entity at the same time.
Yes, it is possible. Just, be careful while using annotation to map your entities each other, otherwise performance of your application will be seriously degraded. Use eager/Lazy fetch wisely. Print out the sql queries that spring-data-jpa/hibernate fires under the hood and analyze.
It is definitely possible.
User
#Entity
public class User {
// id and other attributes ommited
// User and Quiz has OneToMany bidirectional relationship. OP hasn't specified that but I think it makes more sense because a quiz most likely will need to know the user who created it.
#OneToMany (mappedBy="user", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Quiz> quizes;
// ...
}
Quiz
#Entity
public class Quiz {
// id ommitted
#OneToMany
private List<Question> questions;
#ManyToOne
#JoinColumn(name = "user_id") //quiz table will have a column `user_id` foreign key referring to user table's `id` column
private User user;
// ...
}
Question
#Entity
public class Question {
// id ommitted
#OneToMany
#JoinColumn(name="question_id") // Question and Answer has one-to-many unidirectional relationship. `answer` table has a foreign key `question_id` referring to `question.id` column
private List<Answer> answers;
// ...
}
Answer
#Entity
public class Answer {
// ..more attributes
}
Note that:
the entity relationships also depend on your business logic.
If the owner of the bidirectional relationship is different, then your client code needs to adjust. jpa-joincolumn-vs-mappedby
If you want to design your table to be "clean" such that one entity table does not have a foreign key referring to another associated entity. You can create a join table, make the OneToMany relationship "feel" like a ManyToMany and use unique index to enforce the OneToMany. It is up to you. This wikibook page explains pretty well
This is absolutely not the only solution.
I have an EF 4.0 model that has a parent child relationship (say order and orderdetails)
order
{
[primative]
orderid,
ordername,
ordershipping
[navigation]
orderdetails
}
orderdetail
{
orderdetailid,
orderpartid,
orderquantity,
orderpartname
}
My question is how do i load orders with orderdetails where the quantity is greater than 1 in LINQ?
for example
var orders = (from o in context.Orders.Include("OrderDetails")
where....
any ideas?
Okay simple answer actually...
http://msmvps.com/blogs/matthieu/archive/2009/10/07/ef-include-with-where-clause.aspx