Spring Data JPA without entity class - spring-data-jpa

We are using Spring Data JPA + Hibernate approach for implementation.
For complex queries with joins we have created a common mapping xml where we are defining those queries.
We are not creating each entity class for these complex queries.
How can we use JPARepository and execute these query?
Is there any way? Below is one of the query written in orm.xml :
SELECT FMT_NAME( pers.id ) AS customer_name, first_name, mid_name,
last_name,
addr.line_1_addr,
addr.line_2_addr,
RTRIM( LTRIM( addr.city_name || ', ' || addr.state_code || ' ' ||
addr.zip_code_num, ', ') || '-' || addr.zip_code_suffix, '-' ) AS line_3_addr
FROM pers, (SELECT pers_addr.pers_id ,
addr.line_1_addr, addr.line_2_addr,
addr.city_name, addr.state_code,
addr.zip_code_num, addr.zip_code_suffix
FROM pers_addr, addr WHERE addr.id = pers_addr.addr_id
AND TRUNC(SYSDATE) BETWEEN pers_addr.beg_date AND pers_addr.end_date
AND pers_addr.type_code = 'ML'
) addr WHERE pers.id = ? AND pers.id = addr.PERS_ID

You can make use select new the resource for your ordinary class. For example, I have the mapping classes Student, Team, School, Subject and want to get some data from these entities. And build an ordinary class StudentData
So I can do a query(#Query or #NamedQuery) like that:
select new com.my.package.vo.StudentData(student, teacher, subject) from Stutdent student inner join student.team inner join team.teacher ....

Related

How to use a recursive query in a subquery in PostgreSQL

I created a recursive query that returns me a string of the productcategory history (typical parent-child relation:
with recursive productCategoryHierarchy as (
--start with the "anchor" row
select
1 as "level",
pg1.id,
pg1.title,
pg1.parentproductgroup_id
from product_group pg1
where
pg1.id = '17e949b6-85b3-4c87-8f76-ad1e61ea01e1' --parameterize me
union all
-- Get child nodes
select
pch.level +1 as "level",
pg2.id,
pg2.title,
pg2.parentproductgroup_id
from product_group pg2
join productCategoryHierarchy pch on pch.parentproductgroup_id = pg2.id
)
-- Get hierarchy as string
select
CONCAT('',string_agg(productCategoryHierarchy.title, ' > '),'')
from productCategoryHierarchy;
Now I want to use this result in another query as a subquery so that I can use the created string as an attribute in the parent query. Is that possible in Postgres or is there another solution to get a hierarchical tree as string in an attribute?
Are you looking for something like this?
with recursive productcategoryhierarchy as (
...
), aggregated_values as (
select string_agg(productCategoryHierarchy.title, ' > ') as all_titles
from productCategoryHierarchy
)
select ..., (select all_titles from aggregated_values) as all_titles
from ... your main query goes here ..

How to translate the PostgreSQL array_agg function to SQLite?

This query works in PostgreSQL:
Select ot.MCode,array_to_string(array_agg(tk1.TName || ',' || ot.TTime), ' - ') as oujyu_name_list
From TR_A ot
inner join MS_B tk1 on ot.Code = tk1.Code
Where ot.Code in (Select Code From TR_C )
Group byot.MCode
but it does not work in SQLite, because SQLite does not have the array_agg() function. How can this query be converted to SQLite?
For this query, you can use group_concat, which directly returns a string:
SELECT ..., group_concat(tk1.TName || ',' || ot.TTime, ' - ')
FROM ...
SQLite now has the JSON1 extension (which ships in the default distribution) that can group and create arrays of JSON objects. For example,
select
ot.MCode,
json_group_array(json_object('tname', tk1.TName, 'ttime', ot.TTime)) as oujyu_name_list
from TR_A as ot
inner join MS_B as tk1
on (ot.Code = tk1.Code)
where ot.Code in (select code from TR_C)
group by ot.MCode;
The second column will be formatted as a JSON array e.g. [{"tname":...,"ttime":...},...].

Error thrown when trying to chain a text search with a search on a join table that uses group_by

I have three models, Story, Post and Tag. Story is in a one-to-many relationship with Post, and a many-to-many relationship with Tag.
I use the following scope to search for stories that have a least one tag that matches an array of tags:
scope :in_tags, lambda {|category_array, tag_array|
Story.joins('LEFT OUTER JOIN stories_tags ON stories_tags.story_id = stories.id').
joins('LEFT OUTER JOIN tags ON tags.id = stories_tags.tag_id').
where("tags.name in (:tag_array)", :tag_array => tag_array ).
group("stories.id")
}
Note that I use GROUP_BY so that the scope doesn't return a story multiple times if that story has multiple matching tags.
I use the following pg_search_scope to search for stories or posts with specified text:
pg_search_scope :with_text,
:against => :title,
:using => { :tsearch => { :dictionary => "english" }},
:associated_against => { :posts => :contents }
Both of these scopes work fine independent of each other. When I try to chain them together, however, I experience the postgreSQL error:
ActiveRecord::StatementInvalid (PG::Error: ERROR: column "pg_search_79dd68cf7f962ac568b3d7.pg_search_c5f43d73058486e1799d26" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ...e"::text, '')) || to_tsvector('english', coalesce(pg_search_...
^
: SELECT "stories".*, ((ts_rank((to_tsvector('english', coalesce("stories"."title"::text, '')) || to_tsvector('english', coalesce(pg_search_79dd68cf7f962ac568b3d7.pg_search_c5f43d73058486e1799d26::text, ''))), (to_tsquery('english', ''' ' || 'track' || ' ''')), 0))) AS pg_search_rank FROM "stories" LEFT OUTER JOIN stories_tags ON stories_tags.story_id = stories.id LEFT OUTER JOIN tags ON tags.id = stories_tags.tag_id LEFT OUTER JOIN (SELECT "stories"."id" AS id, string_agg("posts"."contents"::text, ' ') AS pg_search_c5f43d73058486e1799d26 FROM "stories" INNER JOIN "posts" ON "posts"."story_id" = "stories"."id" GROUP BY "stories"."id") pg_search_79dd68cf7f962ac568b3d7 ON pg_search_79dd68cf7f962ac568b3d7.id = "stories"."id" WHERE (tags.name in (sports') AND (((to_tsvector('english', coalesce("stories"."title"::text, '')) || to_tsvector('english', coalesce(pg_search_79dd68cf7f962ac568b3d7.pg_search_c5f43d73058486e1799d26::text, ''))) ## (to_tsquery('english', ''' ' || 'track' || ' ''')))) GROUP BY stories.id ORDER BY latest_post_id DESC LIMIT 5000 OFFSET 0):
Is there any way to use pg_search with a scope that requires a join table with a GROUP_BY clause?
I ended up having to switch from the .group() method (which I couldn't seem to get working with pg_search) to select("DISTINCT(stories.id), stories.*). I also made use of ActiveRecords#preload so to eagerly load the associated tag records

Linq to Entities nested subqueries

I am fairly new to linq and am having a problem translating the following sql to linq:
select
c3.COURSE, c3.DESCR
from
(select c.courseprefix, MAX(c.coursesuffix) [coursesuffix]
from
(select distinct SUBSTRING(course,1,3)[courseprefix], RIGHT(course, LEN(course) - 3) [coursesuffix]
from PsCourses where LEN(course) >= 3 ) c
group by c.courseprefix
) c2 inner join PsCourses c3 on (c2.courseprefix + c2.coursesuffix) = c3.COURSE
where
c3.COURSE_STATUS = 'A'
order by
c3.course
Well, you can use http://www.sqltolinq.com/downloads
or you can make a IQueryable, but in my personal criteria the complex queries I prefer to write in native sql

Like and And Or ISNull using Linq to Entity Entity Framework4? How do you do that?

I have a screen in my project " Enquiry" where I user can perform 2 kinds of search.I cannot figure out how to do a "like" or "And or is null" in Linq to entity.
Simple Search ( Search in all fields using "Like" operator)
Advanced Advanced Search (Use "And" Operator)
So lets take these 3 tables and make up a noddy example.
Customer Table (CustomerID,Name,Surname)
Address(AddressID,Street,City)
CustomerOrder (OrderID,OrderName)
Basic search :
this is how I would do it in Sql
SELECT TOP (100) C.Name,C.Surname,CA.Street,CA.City,CO.OrderName
FROM Customer C
LEFT JOIN CustomerAddress CA ON C.CustomerID=CA.CustomerID
LEFT JOIN CustomerOrders CO ON C.CustomerID=CA.CustomerID
WHERE (C.CustomerID LIKE '%' + #SearchText + '%'
OR C.Surname LIKE '%' + #SearchText + '%'
OR C.Name LIKE '%' + #SearchText + '%'
OR CA.Street LIKE '%' + #SearchText + '%'
OR CA.City LIKE '%' + #SearchText + '%'
OR CO.OrderName LIKE '%' + #SearchText + '%') )
Advanced Search
This my sql where clause
WHERE (C.CustomerID =#CustomerID or #CustomerID ISNULL
AND C.Surname =#Surname or #Surname ISNULL
AND C.Name=#Name or #Name ISNULL
AND CA.Street =#Street or #Street ISNULL
AND CA.City =#City or #City ISNULL
AND CO.OrderName =#OrderName or #OrderName ISNULL)
AND ((ModifiedDate BETWEEN ISNULL(convert(varchar,#FromDate,101),'01/01/1901')
AND ISNULL(convert(varchar,#ToDate,101),'12/31/9999'))
How do you do Likes or and or is null in entity framework?
thanks a lot!
For LIKE, you can use Contains, StartsWith, or EndsWith. For IS NULL, use == null.
Example:
var list = from p in Products
where (p.Description.Contains("v") && p.Description.StartsWith("C"))
|| p.MFRCode == "TOYOTA"
|| p.Universal == null
select p;
will cause EF to generate this SQL:
SELECT
[Extent1].[MFRCode] AS [MFRCode],
[Extent1].[MFRProductID] AS [MFRProductID],
[Extent1].[Universal] AS [Universal],
[Extent1].[Description] AS [Description]
FROM [dbo].[Products] AS [Extent1]
WHERE (([Extent1].[Description] LIKE N'%v%') AND ([Extent1].[Description] LIKE N'C%')) OR (N'TOYOTA' = [Extent1].[MFRCode]) OR ([Extent1].[Universal] IS NULL)
and produce these results:
Edit
I used LINQPad to generate these results. It's a great tool, free to use (there's an option to purchase an Intellisense feature), and definitely worth a look if you'd like to experiment with different LINQ queries and see the SQL that EF is generating (it's good for general LINQ experimentation and quickly trying out simple code as well).
int? customerID = null;
string surname = "abc";
var q = from c in oc.Customers
where (customerID == null || c.CustomerID == customerID)
&& (surname == null || c.Surname == surname)
select c;