JPA Join Custom query with OneToMany - spring

I would like to use #Query annotation to create left join query from a entity with a #OneToMany relationship.
Parent entity is :
#Entity
#Table(name="Registration")
public class Registration {
#Column(nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate effect;
#OneToMany(targetEntity=Payment.class, cascade=CascadeType.ALL,fetch = FetchType.LAZY)
#JoinColumn(name="uuid")
private List<Payment> payment;
}
Child :
#Entity
#Table(name="Payment")
public class Payment {
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name="uuid", strategy = "uuid2")
#Column(columnDefinition = "BINARY(16)")
private UUID uuid;
}
For DAO, I do like below :
#Query("SELECT p FROM Registration r JOIN r.payment p WHERE r.effect = :effect")
Iterable<Payment> find(#Param("effect") LocalDate effect);
Obviously, its wrong because generated query is :
select payment1_.uuid as uuid1_9_, payment1_.amount as amount2_9_ from registration registrati0_ inner join payment payment1_ on registrati0_.uuid=payment1_.uuid where registrati0_.effect=?
while the relation table has been generated:
For me, the correct query should be something like this :
select p.* from registration r join registration_payment rp on rp.registration = r.uuid join payment p on p.uuid = rp.payment where r.effect = '2015-10-16'
What is the good query syntax please ? Actual query return en empty array.

Finally, I found a solution.
You must describe relation table with #JoinTable :
#JoinTable(
name="registration_payment",
joinColumns = #JoinColumn(name="registration"),
inverseJoinColumns = #JoinColumn(name = "payment")
)
private List<Payment> payment;
Modify #Query not needed :
#Query("SELECT p FROM Registration r JOIN r.payment p WHERE r.effect = :effect")
Generated query is :
select payment2_.uuid as uuid1_9_, payment2_.amount as amount2_9_
from registration registrati0_
inner join registration_payment payment1_ on registrati0_.uuid=payment1_.registration
inner join payment payment2_ on payment1_.payment=payment2_.uuid
where registrati0_.effect=?

Related

JPQL: Warning: HHH000183, Join query between two entities in different folders

What is the correct way to create Join query between two entities in different folder without using eg. #OneToOne relation ?
I have two entities
First in entity/folder1
package com.test.test.test.model.entity.folder1;
#Entity
#Table(name = "table1")
public class Table1 {
#Column(name = "code", length = 6, updatable = false)
private String code;
}
And second entity in entity/folder2
package com.test.test.test.model.entity.folder2;
#Entity
#Table(name = "table2")
public class Table2 {
#Column(name = "code", length = 6, updatable = false)
private String code;
#Column(name = "postCode", length = 6, updatable = false)
private String postCode;
}
Query in Repository (Query working but return empty response):
#Query("""
SELECT t1 FROM Table1 t1
JOIN com.test.test.test.model.entity.folder2.Table2 t2 ON t1.code = t2.code
WHERE t2.postCode <> ''
""")
Optional<Customer> test1Query();
Warning:
HHH000183: no persistent classes found for query class: SELECT t1 FROM Table1 t1
JOIN com.test.test.test.model.entity.folder2.Table2 t2 ON t1.code = t2.code
WHERE t2.postCode <> ''
I spent a lot of time to fix this but i dont know how.
Thanks for help
Because this repository interface only Customer table use.
For without using eg. #OneToOne relation, you can try use: EntityManager or Criteria API

how can i make query with jpa many to many and list of condition must be all true

I have 2 entities User and Prestation with many to many relationship. I want to get all users having specific Prestation like a list of ID Prestation
my query :
#Query("SELECT distinct u FROM User u JOIN u.prestation p where p.id In (:prestationsList)")
public List<User> findAllUser(#Param("prestationsList") List<Integer> prestationsList);
But this did not give me the correct data, because (In) return user if one element of my prestationList is true
my User :
#Entity
public class User {
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(name = "users_prestations",
joinColumns = {#JoinColumn(name = "user_id")},
inverseJoinColumns = {#JoinColumn(name = "prestation_id")})
private Set<Prestations> prestation = new HashSet<>();
}
my Prestations :
#Entity
public class Prestations {
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "prestation")
private Set<User> user = new HashSet<>();
}
How should I write this query in JPA?
try using this JPQL query
#Query("SELECT * FROM User u left join u.prestation p where p.id In (:prestationsList)")
public List<User> findAllUser(#Param("prestationsList") List<Integer> prestationsList);
if this doesn't work try a native query

HSQL query using limit in join part

I'm new in Spring Boot. I tried to find an answer for my question on SO and google, but I can't find an exact answer for it.
I'm trying to create a function in my Spring Boot JpaRepository class which returns a Customer by id with a limited number of ascending ordered AccountingLogs related to the Customer.
My line of code in JpaRepository:
#Query("select c from Customer left outer join AccountingLog a on a.customer.id = c.id where c.id= :id")
Customer getWithLimitedNumberOfLastTransactions(#Param("id") Long id, #Param("limit") int limit);
The Customer class only with the relevant code:
#Entity
public class Customer {
//...
#OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#Column(nullable = true)
#JsonManagedReference
private Set<AccountingLog> accountingLogs;
//...
}
The customer class only with the relevant code:
#Entity
public class AccountingLog {
//...
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "customer_id")
#JsonBackReference
private Customer customer;
//...
}
So I'm looking for an HSQL query which selects one customer by id with a specified number (variable named limit) of accounting logs in ascending order (last in first) related to the customer.
Thank you for your help!
You can write a native query in #Query if you are using MySql:
#Query(value="select c from Customer left outer join AccountingLog a on a.customer.id = c.id where c.id= :id limit :limit", nativeQuery = true)
or Oracle:
#Query(value="select c from Customer left outer join AccountingLog a on a.customer.id = c.id where c.id= :id and ROWNUM < :limit", nativeQuery = true)

HQL query for Association

I am having below tables here but having some problem while fetching results.
#Entity
#Table(name = "USER_VW")
public class WorkspaceUserImpl
{
#JoinColumn(name = "USER_ID", insertable=false, updatable=false)
#OneToOne(targetEntity = UserImpl.class, fetch = FetchType.EAGER)
private User user;
}
#Table(name = "IK_USER")
#Inheritance(strategy = InheritanceType.JOINED)
#AttributeOverride(name = "id", column = #Column(name = "USER_ID") )
public class UserImpl extends BaseAuditable<UserIdentifier>implements User, UserAuthentication {
private static Logger log = LoggerFactory.getLogger(UserImpl.class);
#Id
#Type(type = "com.commons.UserIdentifierTypeMapper")
#Column(name = "USER_ID")
private UserIdentifier id;
}
and User
Public Inteface User
{
UserIdentifier getId();
}
Now i have written an HQL query to fetch all the data from WorkspaceUserImpl class with a given user ID for UserImpl class like below.
SELECT w from WorkspaceUserImpl w where w.user.id = : user_id;
and also tried
SELECT w from WorkspaceUserImpl as w INNER JOIN w.user as u where u.id = : user_id;
and even tried with JOIN FETCH also
and setting the parameter user_id with some say 1234.
but am getting List as emply for the partcular ID but in DB its having 5 records.
am i making any query mistake here? kindly advice..
Have you tried below query:
from WorkspaceUserImpl as w JOIN FETCH w.user as u where u.id = : user_id;

Add filter on oneToMany mapped table in hibernate/Spring

I am using hibernate4 and spring3.1 in my current project.
I have two tables with one to many mapping. I am using annotation based mapping.
Mappings are done like this :
public class TableA {
#Id
private Long id;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "sample_id")
private Set<TableB> tableBList;
// setter getter
}
public class TableB{
#Id
private Long id;
private Long sample_id;
private Date added_date;
}
When I fired query like this :
String hql = "FROM TableA WHERE id = 5";
return sessionFactory.getCurrentSession().createQuery(hql).list();
It will return all the rows from TableB which are mapped for id =5.
But I want to add one more condition like added_date = XXXX.
Is it possible to add filter in query or by any other way on column added_date ?
Yes it is possible from the query :
look at the hql documentation : http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#queryhql
You want something like
String hql = "select a from TableA as a inner join a.tableBList as b WHERE a.id = :id and b.added_date > :after";
Query q = sessionFactory.getCurrentSession().createQuery(hql);
q.setParameter("id", 5);
q.setParameter("after", date);
q.list();

Resources