How to get a list of "count an entity by an area" in JPA? - spring

I want to get a list containing the number of an entity (count) by an area (each value existing in the table), in JPA.
I found that there is a method that gives the number of an entity by a given value of an area
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
public int countByArea_Libelle(String l);
}
user
#Entity(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String address;
private String name;
}
Is there a method that count an entity with all the value of an area or should i implement it ?

Try this one
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
#Query(value = "select new map( count(u.address) as numberOfUsers, u.address as city ) FROM User u group by u.address")
List<Object> countByAddressList();
}

Try like this
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
long countByAddress(String address);
}

Related

Spring EntityGraphType.FETCH is not working

I am using Spring Boot 2.2.2 . I have faced an unusual issue that EntityGraphType.FETCH did not work whenever I fetch User entity.
It fetches all the FetchType.EAGER (Company, UserFile) entities regardless the EntityGraph type. I tried with attributePaths in repository, it has the same issue.
#Entity
#NamedEntityGraph(name = "User.noAssociation")
#NamedEntityGraph(name = "User.profilePic", attributeNodes = {#NamedAttributeNode("profilePic")})
#Getter
#Setter
public class User extends TimeAudit {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Email
private String email;
#ManyToOne(fetch = FetchType.EAGER)
private Company company;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private UserFile profilePic;
}
and
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
#EntityGraph(value = "User.profilePic", type = EntityGraphType.FETCH)
#Query("SELECT u FROM User u WHERE u.email="email")
User findByEmail(String email);
}
Change
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
#EntityGraph(value = "User.profilePic", type = EntityGraphType.FETCH)
#Query("SELECT u FROM User u WHERE u.email="email")
User findByEmail(String email);
}
to
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
#EntityGraph(value = "User.profilePic", type = EntityGraphType.LOAD)
#Query("SELECT u FROM User u WHERE u.email="email")
User findByEmail(String email);
}

How to Inner Join using Spring Boot JPA / Hibernate in Repository?

I am currently learning spring boot , hibernate and Spring Boot JPA
I developing a Classroom App for coaching centers and institutes .
In it, students enrolled to multiple courses in a single institute
The Student Entity class :
#Entity
#Table(name = "student")
public class Student {
private String name;
private String dob;
private String gender;
private String address;
private String email;
private Integer mobile;
private String joined;
private Integer instID;
#Id
private String studentid;
getters and setters()....
}
Course Table Entity class
#Entity
#Table(name = "courses")
public class Course {
private String name;
private String description;
private String logo;
private String start;
private String end;
private Integer fee;
#Id
private String courseid;
private Integer instID;
getters and setters();
}
Enrolled Classes Table's Entity class
public class EnrolledCourses {
#Id
String enrollID;
String courseid;
String studentid;
Date joined;
getters and setters()...
}
JPA Repository
#Repository
public interface StudentRepository extends CrudRepository<Student, String> {
Student findTopByInstIDOrderByStudentidDesc(int instID);
}
#Repository
public interface CourseRepository extends CrudRepository<Course,String> {
}
#Repository
public interface EnrolledRepository extends CrudRepository<Course,String> {
}
My Need
Now I am retrieving enrolled students for a given course in a given institute... by using this MySQL query
SELECT
`enrolled_courses.enrollID`,
`student.name`, `student.studentid`
FROM `enrolled_courses`
INNER JOIN `student`
WHERE
`enrolled_courses.studentid` = `student.studentid`
AND
`student.instID` = 13
AND
`enrolled_courses.courseid` = '13I01C' ;
Now I need to implement this Inner join query in CourseRepository (or enrolledstudent repo)
How to achieve this ?
Please guide me
If we use hibernate mapping in EnrolledCourses entity like
#Entity
public class EnrolledCourses {
#Id
String enrolledId;
#ManyToOne
Student student;
#ManyToOne
Course course;
Date joined;
getters and setters()...
}
from the above mappings without using any SQL queries, you can retrieve all student who comes under a particular course
By using the method in the interface
#Repository
public interface EnrolledRepository extends CrudRepository<EnrolledCourses,String> {
List<EnrolledCourses> findByCourse_CourseId(String courseId);
}
if we have some relations between the entities we can easily retrieve all the fields using Jpa.

How to change method names from jpa-repository?

There is application on spring+jpa(repositories)
Entity:
#Entity
#Getter
#Setter
#NoArgsConstructor
public class User{
private int id;
private String name;
private String surname;
private int age;
}
So, my repository looks like this:
#Repository
public interface UserRepository extends CrudRepository<User, Integer>{
public List<User> findUsersByNameAndAge(String name, int age);
public List<User> findUsersByNameAndSurname(String name, String surname);
}
In my real prod code, there too much params, so this method-name is too long and not comfortable.
Is there a way to make from long method names comfortable options, like just find?
Use default Java 8 feature for wrapping :
for example :
interface UserRepository extends JpaRepository<User, Long> {
// don't use that crazy long method! use getByEmail instead
User findFirstByEmailContainsIgnoreCaseAndField1NotNullAndField2NotNullAndField3NotNullAndField4NotNullAndField5NotNullAndField6NotNull(final String email);
default User getByEmail(final String email) {
return findFirstByEmailContainsIgnoreCaseAndField1NotNullAndField2NotNullAndField3NotNullAndField4NotNullAndField5NotNullAndField6NotNull(email);
}
}
You can find complete reference here : https://github.com/daggerok/spring-data-examples/blob/master/shadov/src/main/java/daggerok/ShadovApplication.java
Or else You can specify any name for a method and add an annotation #Query with parameter value which holds desired query to database like this:
#Query(value="select u from User u where u.deleted=false and u.email=:email")
User findOneByEmail(#Param("email")String email);
or, with native sql query:
#Query(value="SELECT * FROM users WHERE deleted=false AND email=?1", nativeQuery=true)
User findOneByEmail(String email);
You can also use names that follow the naming convention for queries since #Query annotation will take precedence over query from method name.

How to search through array in Spring Boot CrudRepository

Say, I have the following entity class:
Person.java
#Entity
public class Person {
#Id
private String name;
private String[] cars;
// Constructor, getters and setters
}
And the repository:
PersonRepository.java
public interface PersonRepository extends CrudRepository<Person, String> {
// this is unclear!
List<Person> getAllByCars...(String car)
}
Is there a method that returns all persons, whose car array contains one given car (the String parameter above)?
For me, it seems that all supported JPA keywords can only deal with single elements, but not with arrays.
Thanks for help!
Ideally, You should declare cars as a separate Entity like this
#Entity
public class Person {
#Id
private String name;
private List<Car> cars;
// Constructor, getters and setters
}
If not you should change Array to List at the least.
change
private String[] cars;
to
#ElementCollection
private List<String> cars;
Then You have to write a Query like this
#Query("select p from Person p WHERE :car in elements(p.cars)")
List<Person> getAllByCars...(#Param("car") String car)
I'm guessing at how you are currently storing the cars information and suggesting a possible solution:
#Entity
public class Car {
#Id
private String name;
#Column
private String person_name;
}
public interface CarRepository extends JpaRepository<Car, String> {
//Result will have all cars with the person_name identifying the Person #Entity
List<Car> findByName(String name);
}

Is there a repostiory implementation for cross store entities (#Entity #NodeEntity(partial = true))

I have an entity which would be stored in both relational(MySql) and graph database(Neo4j).
#Entity
#NodeEntity(partial = true)
public class User {
#NotNull
#Column(name = "UserName", unique = true)
private String userName;
#GraphProperty
String firstName;
}
I know we have JpaRepository and GraphRepository.
public interface UserRepository extends JpaRepository<User, Long> { }
public interface UserGraphRepository extends GraphRepository<User> { }
But is there any repository implementation for handling such a cross store entity? So I could do something like this.
public interface UserRepository extends CrossStoreRepository<User, Long> { }
So when I call save, it should save in both the databases.
I did some searching and found nothing.So started writing one myself.
If no such thing exist, is there a plan to add one in the future?
Is there any reason why you can't use spring-data-neo4j-cross-store as it is part of the spring-data-neo4j distribution?

Resources