Write query in QueryDsl - spring-data

I am using spring-data, QueryDsl etc
Say I have two entities,
#Entity
Person {
#Id
Integer id;
String name;
#OneToMany
List<Address> addresses;
}
#Entity
Address {
#Id
Integer id;
String city;
}
One Person can have many addresses.
I am trying to write query in QueryDSL for following,
Give me list of persons who's city name starts with 'xyz'.
What I did so far,
class PersonPredicates {
public static BooleanExpression cityStartsWith(String city) {
QPerson person = QPerson.person;
return person.addresses. // could not get how to create predicate for this
}
}
Thank you for response.

Related

Spring Data JPA Projection nested list projection interface

I have a question about usage of nested list projection interface. I have two entity (Parent and child) (they have Unidirectional association)
Parent =>
#Table(name = "parent")
#Entity
public class ParentEntity {
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
// other fields........
}
Child =>
#Table(name = "child")
#Entity
public class ChildEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#NonNull
private String name;
#NonNull
#ManyToOne(fetch = FetchType.LAZY)
private ParentEntity parent;
// other fields........
}
I have two projection interface for select specific columns.
ParentProjection =>
public interface ParentProjection {
String getName();
Set<ChildProjection> getChild();
}
ChildProjection =>
public interface ChildProjection {
String getId();
String getName();
}
I want to take list of ParentProjection which includes with list of ChildProjection.
Repository query like that =>
#Query("select p.name as name, c as child from ParentEntity p left join ChildEntity as c on p.id = c.parent.id")
List<ParentProjection> getParentProjectionList();
This query works, but it selects all columns of ChildEntity, and map only id, name propeties to ChildProjection. (generated query selects all columns, but i want to select only id and name columns)
How can i select only id and name columns (select specific columns for nested list projection interface) and map to ChildProjection fields (using with #Query) ?
Note: I don't need to use class type projection.
You need to add the OneToMany relation to ParentEntity and annotate with Lazy.
Hope it helps (i have tried this).

Storing enum in separate table

I have entity Student and it has field like enum City. I know how to store enums in jpa via #Enumerated annotation, but I want to store enum in separate table and have foreign key from Student to City. But I have no idea how to implement.
City
public enum City {
PAVLOGRAD("Pavlograd")
,DNEPR("Dnepr");
private String shortName;
City(String shortName) {
this.shortName = shortName;
}
public String getShortName() {
return shortName;
}
}
Student
public class Student implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Enumerated(EnumType.ORDINAL)
private City city;
}

Model Look up table for a JPA Entity Field

I'm trying to find out the appropriate relationship to be used in order to model an JPA Entity Field which needs a Look-up table (Comboxbox equivalent on the UI) to select the value from. An example below:
#Entity
public class Employee {
#Id
private int employeeId;
private String name;
private Department department;
}
#Entity
public class Department {
#Id
private int id;
private String name;
}
The instances of Department could be as follows:
Id | Name
-----------------------
100 | Human Resources
101 | Sales
102 | Finances
For an employee, the department field should get a value from one of the above. What should be the JPA annotations for the corresponding fields in both the entities?
Thanks,
Sandeep Joseph
I think you are looking for a unidirectional ManyToOne relationship from Employee to Department, something like this:
#Entity
public class Employee {
#Id
private int employeeId;
private String name;
#ManyToOne
#JoinColumn(name = "department_id", nullable = false)
private Department department;
}
This means an employee must be associated to a single department and a department can be associated to many employees.
If you need to know the list of employees associated to a department then you can make the relationship bidirectional by adding this:
#Entity
public class Department {
#Id
private int id;
private String name;
#OneToMany(mappedBy = "department")
private Collection<Employee> employees;
}

Query an embedded collection inside an entity using Datanucleus and mongodb

I was trying to query a embedded collection inside an entity using a query similar to the following:
Query q = em.createQuery("SELECT u FROM User u , in (u.addresses) a
WHERE a.state='xx'");
The query didn't return any result nor did it throw any error. I am using Datanucleus and MongoDb. Does Datanucleus have any limitation on such queries?
And the entity looked like:
public class User{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
protected long id;
#ElementCollection
protected List<Address> addresses;
public User(){
}
...
#Embeddable
public class Address {
private String street;
private String city;
private String state;
private Integer zip;
public Address(){
}
...

JPA Query Many To One nullable relationship

I have the following entities and would like to seek help on how to query for selected attributes from both side of the relationship. Here is my model. Assume all tables are properly created in the db. JPA provider I am using is Hibernate.
#Entity
public class Book{
#Id
private long id;
#Column(nullable = false)
private String ISBNCode;
#ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY, optional = false)
private Person<Author> author;
#ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY, optional = true)
private Person<Borrower> borrower;
}
#Inheritance
#DiscriminatorColumn(name = "personType")
public abstract class Person<T>{
#Id
private long id;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Info information;
}
#Entity
#DiscriminatorValue(PersonType.Author)
public class Author extends Person<Author> {
private long copiesSold;
}
#Entity
#DiscriminatorValue(PersonType.Borrower)
public class Borrower extends Person<Borrower> {
.....
}
#Entity
public class Info {
#Id
private long id;
#Column(nullable=false)
private String firstName;
#Column(nullable=false)
private String lastName;
......;
}
As you can see, the book table has a many to one relation to Person that is not nullable and Person that is nullable.
I have a requirement to show, the following in a tabular format -
ISBNCode - First Name - Last Name - Person Type
How can I write a JPA query that will allow me to select only attributes that I would want. I would want to get the attributes ISBN Code from Book, and then first and last names from the Info object that is related to Person Object that in turn is related to the Book object. I would not want to get all information from Info object, interested only selected information e.g first and last name in this case.
Please note that the relation between the Borrower and Book is marked with optional=true, meaning there may be a book that may not have been yet borrowed by someone (obviously it has an author).
Example to search for books by the author "Marc":
Criteria JPA Standard
CriteriaQuery<Book> criteria = builder.createQuery( Book.class );
Root<Book> personRoot = criteria.from( Book.class );
Predicate predicate = builder.conjunction();
List<Expression<Boolean>> expressions = predicate.getExpressions();
Path<Object> firtsName = personRoot.get("author").get("information").get("firstName");
expressions.add(builder.equal(firtsName, "Marc"));
criteria.where( predicate );
criteria.select(personRoot);
List<Book> books = em.createQuery( criteria ).getResultList();
Criteria JPA Hibernate
List<Book> books = (List<Book>)sess.createCriteria(Book.class).add( Restrictions.eq("author.information.firstName", "Marc") ).list();
We recommend using hibernate criterias for convenience and possibilities.
Regards,