简体   繁体   中英

Spring boot jpa table hierarchy

I have just one table in the database named Student . Below is the jpa entity against it in my code:

@Entity
@Table(name = "student")
public class Student{

@Id
private Long id;

@Column
private String firstName;

@Column
@Embedded
@JsonUnwrapped
private School school;
}

public class School{

private Integer grade;//eg. 2nd, 3rd

private String type; //eg. primary, secondary
}

Until now, the code was only to fetch all the students and their data or to fetch a particular student. So, the DB schema was such. But now, we have a new functionality wherein we need to search based on a particular grade and fetch all students for that particular grade. OR fetch all students for a particular school type eg. all students in the primary school. So, the requirement has totally reversed such that we need to send the return the below schema to the front end:

class SchoolResponseDTO{

private String schoolType;

private List<Integer> grades;
}

class Grade{

private Integer id;

private List<Integer> studentId;
}

To be a bit verbose, from now on, we need to find all the school types, then, all the grades in that school types, and then, all the students in that school type and grade.

Until now, we were using the Spring JpaRepository for our requirements. I feel this new requirement would require custom queries and I dont think this can be handled in a straight forward manner using the JPARepository. I just need to know what do you think. Can this be done without custom sql queries?

You can use Spring Data and use something like this query property expressions. From the doc:

Property expressions can refer only to a direct property of the managed entity, as shown in the preceding example. At query creation time, you already make sure that the parsed property is a property of the managed domain class. However, you can also define constraints by traversing nested properties. Consider the following method signature:

List<Person> findByAddressZipCode(ZipCode zipCode);

Assume a Person has an Address with a ZipCode. In that case, the method creates the property traversal x.address.zipCode. The resolution algorithm starts by interpreting the entire part (AddressZipCode) as the property and checks the domain class for a property with that name (uncapitalized). If the algorithm succeeds, it uses that property. If not, the algorithm splits up the source at the camel case parts from the right side into a head and a tail and tries to find the corresponding property — in our example, AddressZip and Code. If the algorithm finds a property with that head, it takes the tail and continues building the tree down from there, splitting the tail up in the way just described. If the first split does not match, the algorithm moves the split point to the left (Address, ZipCode) and continues.

Although this should work for most cases, it is possible for the algorithm to select the wrong property. Suppose the Person class has an addressZip property as well. The algorithm would match in the first split round already, choose the wrong property, and fail (as the type of addressZip probably has no code property).

To resolve this ambiguity you can use _ inside your method name to manually define traversal points. So our method name would be as follows:

List<Person> findByAddress_ZipCode(ZipCode zipCode);

Because we treat the underscore character as a reserved character, we strongly advise following standard Java naming conventions (that is, not using underscores in property names but using camel case instead).

Check the link https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM