JPA inner join query syntax help required - java

I was wondering if you guys could help me with an OpenJPA query I am trying to write.
I have an ItemEntity...
#Entity(name = "item")
public class ItemEntity implements java.io.Serializable {
#Id
#GeneratedValue(strategy = GenerationType.TABLE, generator = "itemid")
#TableGenerator(name = "itemid", table = "items_sequence", allocationSize = 1)
private Long id;
#ManyToOne
private ImportPayloadEntity importPayloadEntity;
And a ImportPayloadEntity...
#Entity(name = "import_payload")
public class ImportPayloadEntity implements java.io.Serializable{
#Id
#GeneratedValue(strategy = GenerationType.TABLE, generator = "importpayloadid")
#TableGenerator(name = "importpayloadid", table = "import_payload_sequence", allocationSize = 1)
private Long id;
#Column(name = "PROCESSED_IND")
private String processedInd;
I am trying to select from my item entity joining back to my import payload entity to ensure that the processedInd is equal to 'N'.
I can't quite get the correct syntax. I've tried a few things but here is my latest attempt..
#NamedQuery(name = "queryItems", query = "SELECT c1, c2 FROM item c1 INNER JOIN c1.importPayloadEntity c2 WHERE c2.processedInd='N'")
This gives me...
Unknown column 't0.IMPORTPAYLOADENTITY_ID' in 'on clause' {prepstmnt 1719904819 SELECT t0.id, t1.id, t1.FILENAME, t1.LOAD_DATETIME, t1.IMPORT_PAYLOAD_BODY, t1.IMPORT_PAYLOAD_TYPE, t1.PROCESSED_DATETIME, t1.PROCESSED_IND FROM item t0 INNER JOIN import_payload t1 ON t0.IMPORTPAYLOADENTITY_ID = t1.id WHERE (t1.PROCESSED_IND = ?)} [code=1054, state=42S22]
Appreciate your help.

You can try select i from Item i where i.importPayloadEntity.processedInd = 'N'

Related

Select from table using parameters from related tables

I have 3 tables (Entities) (postgreSQL):
#Entity
#Table(name = "application", schema = "applications")
public class Application implements Serializable {
#Id
#GeneratedValue
#Column(name = "application_id")
private long applicationId;
#Column(length = 400)
#Size(min=50, max=400)
private String applicationDescribing;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "customerId")
private Customer Customer;
.....
Also I have the abstract class User with child class Customer, which has its own table in DB.
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private Long userId;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "localitiesId")
private Localities userLocality;
.....
#Entity
#AttributeOverride(name="userId", column=#Column(name="customerId"))
public class Customer extends User {
#Column(length = 8)
private String userType;
.....
User and also Customer table has many to one related table Locality, connected via id.
#Entity
#Table(name = "localities", schema = "resource")
public class Localities implements Serializable {
#Id
#GeneratedValue
#Column(name = "id")
private long localitiesId;
#Column(name = "region", length = 50)
private String region;
....
I try to realize seaching via Application, using (String) keyWord and locality_id (long) locality.
First approach:
#Query(value = "SELECT u FROM Application u WHERE u.applicationDescribing LIKE %:keyWord% " +
"AND userLocality IN (SELECT c FROM User c WHERE c.userLocality IN " +
"(SELECT l FROM Localities l WHERE l.localitiesId = :locality))")
List<Application> getApplicationsByKeyWordsAndRegion(#Param("keyWord") String keyWord, #Param("locality") long locality);
Second approach (recomended by richyen):
#Query(value = "SELECT a FROM Application a " +
"JOIN Customer c ON a.customerid = c.userid " +
"JOIN Localities L ON c.localitiesid = L.id " +
"WHERE a.applicationDescribing LIKE %:keyWord% AND L.id = :locality")
List<Application> getApplicationsByKeyWordsAndRegion(#Param("keyWord") String keyWord, #Param("locality") long locality);
Both dont work. As a result I need List <Application>, which have "keyWord" in describing field and locality in Application.Customer.locality_id. Please help
Is this what you're looking for?
SELECT a.*
FROM application a
JOIN (SELECT * FROM customer c UNION ALL SELECT * FROM executor e) as u on a.customer_id=u.id
JOIN locality l on u.locality_id=l.id
WHERE a.description like '%<keyWord>%'
AND l.region = <region>;
I guess one question I have for you is: how do you differentiation between Customer ID and Executor ID?
Correct answer:
SELECT app FROM Application app
INNER JOIN app.Customer customer
INNER JOIN customer.userLocality
locality WHERE customer.userLocality.id
= :locality AND app.applicationDescribing
LIKE CONCAT('%',:keyWord,'%')

JPA: how to select data by child ID in OneToMany relation

I have two models Quality and ExpertsData:
#Entity(name = "QualityDepartmentData")
#Table(name = "quality")
public class QualityDepartmentData {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "qualityId")
private List<ExpertsData> ListOfExpertsData;
#Entity(name = "ExpertsData")
#Table(name = "experts")
public class ExpertsData {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private Long qualityId;
private Integer expertId;
I need to fetch list of QualityDepartmentData by the expertId. Right now I can do it by native MySQL query, like this:
#Query(value = "SELECT * FROM quality INNER JOIN experts ON quality.id = experts.quality_id WHERE experts.expert_id = ?1", nativeQuery = true)
Page<QualityDepartmentData> findAllForExpertId(long id, Pageable pageable);
That is working, but the problem is that the native query can't be dynamically sorted, so I need to write query in JPQL for ability to use org.springframework.data.domain.Pageable.
Can't find any examples for such event in official JPA docs. Also I tryed many vatiants like this, but it's not working:
#Query(value = "SELECT d FROM QualityDepartmentData d INNER JOIN ExpertsData c ON d.id = c.qualityId WHERE c.expertId = ?1")
#Query(value = "SELECT distinct q FROM QualityDepartmentData q JOIN q.ListOfExpertsData e WHERE e.expertId = ?1")
Page<QualityDepartmentData> findAllForExpertId(Integer id, Pageable pageable);
That is working. Thanks for link to example to JB Nizet!

How to join fetch two associations with JPA/Hibernate

I am new to Hibernate and really need help from you guys....
I have following class: UserActionPerUserResult
#Entity
#Table(name = "user_action_per_user_result")
public class UserActionPerUserResult {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "user_email", nullable = false)
private String userEmail;
#ManyToOne
#JoinColumn(name = "user_action_id", nullable = false)
private UserAction userAction;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name="user_action_per_user_result_email_message",
joinColumns={#JoinColumn(name="user_action_per_user_result_id", referencedColumnName="id")},
inverseJoinColumns={#JoinColumn(name="email_message_id", referencedColumnName="id")})
#JsonIgnore
private List<EmailMessage> emailMessages;
....getters/setter....
}
In MYSQL, the UserActionPerUserResult is one table and for email Messages, there is another table called as UserActionPerUserResultEmailMessage which has email messages associate with id of the table UserActionPerUserResult.
I have all the data stored in the MySQL table, however I am not able to query it. I need to write a query to fetch the list of emailMessages. I am trying the following, but it is throwing exception.
TypedQuery<UserActionPerUserResult> messagesQuery = entityManager.createQuery(
"SELECT e from UserActionPerUserResult e JOIN UserActionPerUserResult.emailMessages e1 WHERE e.id = 1 and e.userAction = 1", UserActionPerUserResult.class);
List<UserActionPerUserResult> resultList = messagesQuery.getResultList();
Try writing the query like this:
TypedQuery<UserActionPerUserResult> messagesQuery = entityManager.createQuery(
"SELECT e from UserActionPerUserResult e JOIN FETCH e.emailMessages em WHERE e.id = 1 and e.userAction.id = 1", UserActionPerUserResult.class);
List<UserActionPerUserResult> resultList = messagesQuery.getResultList();
The join is using the root entity alias
The userAction.id is used against userAction, when matching against a numerical value

NamedQuery miss places table in OnetoOne relation

i have a problem with named query in my project. I have 2 entities with OneToOne relation.
#Entity
#Table(name = "SL_BRANCH_PARAMS")
public class BranchParams implements Identifiable {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.AUTO, generator = "SL_BRANCH_PARAM_SEQ_GEN")
#SequenceGenerator(name = "SL_BRANCH_PARAM_SEQ_GEN", sequenceName = "SL_BRANCH_PARAM_SEQ")
private Long id;
#JoinColumn(name = "INTEREST_ACCOUNT_ID")
#OneToOne(fetch = FetchType.EAGER)
private AccountDef interestAccount;
}
and second class with named query
#Entity
#Table(name = "SL_ACCOUNT_DEF")
#NamedQueries({
#NamedQuery(name = "AccountDef.getAvaibleInterestAccountsForBranch",
query = "SELECT ad FROM AccountDef ad LEFT JOIN FETCH ad.branchParamsInterest WHERE ad.branchParamsInterest = NULL ORDER BY ad.id ASC"),
})
public class AccountDef implements Identifiable {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.AUTO, generator = "SL_ACCOUNT_DEF_SEQ_GEN")
#SequenceGenerator(name = "SL_ACCOUNT_DEF_SEQ_GEN", sequenceName = "SL_ACCOUNT_DEF_SEQ")
private Long id;
#OneToOne(fetch = FetchType.EAGER, mappedBy = "interestAccount")
private BranchParams branchParamsInterest;
}
When i execute the named query I get this query to database
select
accountdef0_.ID as ID1_10_0_,
branchpara1_.ID as ID1_13_1_,
branchpara1_.INTEREST_ACCOUNT_ID as INTERES16_13_1_
from
SL_ACCOUNT_DEF accountdef0_
left outer join
SL_BRANCH_PARAMS branchpara1_
on accountdef0_.ID=branchpara1_.INTEREST_ACCOUNT_ID
where
accountdef0_.ID is null //this is incorrect
order by
accountdef0_.ID ASC
which is not correct because it gives me no rows as it checks if the ID in AccountDef is null instead in BranchParams.
The correct query should look like this
select
accountdef0_.ID as ID1_10_0_,
branchpara1_.ID as ID1_13_1_,
branchpara1_.INTEREST_ACCOUNT_ID as INTERES16_13_1_
from
SL_ACCOUNT_DEF accountdef0_
left outer join
SL_BRANCH_PARAMS branchpara1_
on accountdef0_.ID=branchpara1_.INTEREST_ACCOUNT_ID
where
branchpara1_.ID is null //this is correct
order by
accountdef0_.ID ASC
and such query returns the rows i want. And the question from me is, why named query checks null id value for AccountDef instead for BranchParams?
Perhaps something like this?
#NamedQuery(name = "AccountDef.getAvaibleInterestAccountsForBranch",
query = "SELECT ad FROM AccountDef ad LEFT JOIN FETCH ad.branchParamsInterest bp WHERE bp.interestAccount = NULL ORDER BY ad.id ASC")

JPA Query - JOIN Clause

I have two tables
Table A
Table B
Table A contains
Column X
Column Y
Column Z
Column W
Tables B Contains
Column P
Column Q
Column R
Column W
Column W is common in both the tables.
and their entities
First Entity
#Entity
#Table(name = "A")
#Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class TableA extends AbstractBaseEntity {
#Id
#NotNull
#Column(name = "X")
private Long sampleId1;
#Id
#NotNull
#Column(name = "Y")
private Long sampleId2;
#Id
#NotNull
#Column(name = "Z")
private Date sampleDate3;
#ManyToOne(targetEntity = TableB.class)
#JoinColumn(name = "W")
private TableB tableB;
...
getter
setter
....
}
Second Entity
#Entity
#Table(name = "TableB")
#Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class TableB extends AbstractBaseEntity {
#Id
#NotNull
#Column(name = "W")
private Long sampleId4;
#Id
#NotNull
#Column(name = "P")
private Long sampleId1;
#Id
#NotNull
#Column(name = "Q")
private Long sampleId2;
#Id
#NotNull
#Column(name = "R")
private Long sampleId3;
...
getter
setter
....
}
I have an Interface where all the queries are written
Public interface sqlquery{
String query1 = "from TableA ORDER BY" +
sampleDate3 asc;";
String query2= "from TableB";
}
Right now i am fetching all data separately in these query,
I need some help in writing a new single query where data should be shown on the basis of same ID i.e SampleId4(column W)
using JOIN clause and where.
and store the data in result list.
Your mapping doesn't make much sense. If all the columns in table B are part of the ID, that probably means that you might have several rows in it which have the same value in column W. So, if a row in table A has this shared value, it actually references all these rows of table B. So you don't have a ManyToOne association between TableA and TableB.
Regarding your query, since the mapping is wrong in the first place, I don't see how I could write it. End even if it was OK, you should tell us what the query should return, because it's far from being clear.

Categories