Spring JPA Method name for a 2 table query using #Query - java

EDITTED
Curious... I have a custom Spring JPA query which I'm not sure how to write.
I'm extending PagingAndSortingRepository
The #Query: select * from Table1 tb1 JOIN Table2 tb2 on tb1.id = tb2.tb1_id
where tb2.personId = :personId and tb1.mainId=:mainId and tb2.status in (:statusList)
I'm not sure how to create the method name for this as it keeps giving me an error saying it can't find status in the Table1.
I figured something like:
public Page findByMainIdAndStatusInAndPersonId(#Param("mainId") Integer mainId, ..........); would work but it's telling me it can't find status. Which is understandable since status is in the Table2 object which I'm trying to join on.
**Table1**
id
column1
column2
mainId
List<Table2> table2List
**Table2**
id
table1_id
status
person_id
table 1 and 2 are linked via table2's table_id column. however in the Table1 JPA repository, I need to fetch all of Table1 based on criteria in Table2.
I checked "property expressions" but I'm not catching how to write the jpa method name
Thanks guys :)

After a while of looking around and trying different things... ANSWER:
When you want to query on Table2, you need to add it to the method as:
findBymainIdAndTable2List_StatusInAndTable2List_personId
So essentially add the list name followed by underscore and the column name in that table. If anyone wants to add more, def feel free :D This is how I got it to work

Related

Insert values in many to many relationship tables with JOOQ

I have three tables in my database, SUBSCRIPTION, USER_ID, and an association table called SUBSCRIPTION_USER_ID.
My strategy is to use JOOQ batch with three queries, the first one to insert on row into SUBSCRIPTION, the second query to insert multiple rows into USER_ID, and finally, I need to insert the association IDs into SUBSCRIPTION_USER_ID, so I did the following:
InsertValuesStep2 insertUserIds = insertInto(
USER_ID, USER_ID.USER_ID_TYPE, USER_ID.USER_ID_VALUE);
for (String userId : subscriptionDTO.getUserId())
insertUserIds = insertUserIds.values(getValue(0, userId), getValue(1, userId));
InsertReturningStep insertReturningUserIds = insertUserIds.onConflictDoNothing();
InsertResultStep insertReturningSubscription = insertInto(SUBSCRIPTION)
.set(SUBSCRIPTION.CHANNEL_ID, subscriptionDTO.getChannel())
.set(SUBSCRIPTION.SENDER_ID, subscriptionDTO.getSenderId())
.set(SUBSCRIPTION.CATEGORY_ID, subscriptionDTO.getCategory())
.set(SUBSCRIPTION.TOKEN, subscriptionDTO.getToken())
.onConflictDoNothing()
.returningResult(SUBSCRIPTION.ID);
Unfortunately, to insert values into the association table, I tried many ways but nothing works for me, finally, I tried to insert values in SUBSCRIPTION_USER_IDusing with select but It doesn't work:
InsertValuesStep insertValuesSubscriptionUserIds = insertInto(
SUBSCRIPTION_USER_ID,
SUBSCRIPTION_USER_ID.SUBSCRIPTION_ID,
SUBSCRIPTION_USER_ID.USER_ID_ID)
.select(select(SUBSCRIPTION.ID, USER_ID.ID)
.from(SUBSCRIPTION)
.innerJoin(USER_ID)
.on(concat(USER_ID.USER_ID_TYPE,
val(CATEGORY_USER_ID_DELIMITER),
USER_ID.USER_ID_VALUE).in(subscriptionDTO.getUserId())
.and(SUBSCRIPTION.SENDER_ID.equal(subscriptionDTO.getSenderId()))
.and(SUBSCRIPTION.CHANNEL_ID.equal(subscriptionDTO.getChannel()))
.and(SUBSCRIPTION.CATEGORY.equal(subscriptionDTO.getCategory()))
.and(SUBSCRIPTION.TOKEN.equal(subscriptionDTO.getToken()))));
Am I missing something above? Is there a better way using JOOQ to insert many-to-many relationship values or to use queries results as parameters for other queries?
I'm assuming you posted your entire code. In case of which:
You don't call execute on your USER_ID insertion
Simply add
insertUserIds.onConflictDoNothing().execute();
Or alternatively, fetch the generated IDs using a call to returning().fetch()
Inner join
This might just be a stylistic question, but what you seem to be doing is a cross join. Your INNER JOIN filters aren't really join predicates. I'd put them in the WHERE clause. Clarity may help avoid further problems in such a query.
Specifically, that first "join predicate" is very confusing, containing a CONCAT call, which isn't something one would see in an INNER JOIN every day, and only touches one table, not both:
.on(concat(USER_ID.USER_ID_TYPE,
val(CATEGORY_USER_ID_DELIMITER),
USER_ID.USER_ID_VALUE).in(subscriptionDTO.getUserId())
Wrong predicate
That last predicate seems wrong. You're inserting:
.set(SUBSCRIPTION.TOKEN, subscriptionDTO.getToken())
But you're querying
.and(SUBSCRIPTION.TOKEN.equal(subscriptionDTO.getContactId()))));
That should probably be subscriptionDTO.getToken() again
As mentioned above, I have inserted values for SUBSCRIPTION and USER_ID tables. And get for the association table I need to get the IDs of the already inserted values from the above two tables, so to solve the issue I've used this query to insert in SUBSCRIPTION_USER_ID:
InsertReturningStep insertReturningSubscriptionUserId = insertInto(
SUBSCRIPTION_USER_ID,
SUBSCRIPTION_USER_ID.SUBSCRIPTION_ID,
SUBSCRIPTION_USER_ID.USER_ID_ID)
.select(select(SUBSCRIPTION.ID, USER_ID.ID).from(SUBSCRIPTION
.where(concat(USER_ID.USER_ID_TYPE, val(CATEGORY_USER_ID_DELIMITER), USER_ID.USER_ID_VALUE).in(subscriptionDTO.getUserId()))
.and(SUBSCRIPTION.SENDER_ID.equal(subscriptionDTO.getSenderId()))
.and(SUBSCRIPTION.CHANNEL_ID.equal(subscriptionDTO.getChannel()))
.and(SUBSCRIPTION.CATEGORY.equal(subscriptionDTO.getCategory()))
.and(SUBSCRIPTION.TOKEN.equal(subscriptionDTO.getToken()))).onConflictDoNothing();
Finally, I have executed all the queries using batch:
using(configuration).batch(insertReturningSubscription,
insertReturningUserIds,
insertReturningSubscriptionUserId).execute()

How to select a table by parameters in jasper report using java in eclipse?

I have a button. When I hit it. It creates a table in database with name+billno+date. and inserts all details like product name and etc into the database.
Now I want to when the new table is created, after that jasper report fetch that newly created table and show it in table of jasper report.
For that I created a parameter.
Hashmap param = new Hashmap();
param.put("TABLE" , name+bill+date);
After that I created a table in jasper report and tried to do this query.
select * from $P{TABLE}
But it throws an error.
You have to correct the query using $P!{} syntax (note the ! char between P and {):
SELECT * FROM $P!{TABLE}
Where $P!{TABLE} is replaced with the text value of the parameter (table name in this case).
$P{} syntax can be used in the case the parameter is used as standard SQL parameter, it means that the query can be executed using a prepared statement. For example:
SELECT * FROM bill WHERE id = $P{ID}
Where prepared statement is then:
SELECT * FROM bill WHERE id = ?
Side note: It looks like a little bit crazy scenario to create separate table for each combination of name + billno + date. Imagine that on some day you will need to implement search through all those records - how you will create SELECT query over all those tables?
It would be better to have one table (bill for example) with id column as a primary key, and other columns like name, billnum and date and pass that id into the Jasper report as a parameter. Products can be stored in the related table bill_item and relate them to bill by bill_id column. Then in Jasper report you can SELECT * FROM bill b LEFT JOIN bill_item i ON i.bill_id = b.id WHERE b.id = $P{ID}. But I'm just guessing how can look your data model.

JOIN 2 tables and select specific rows

I use Wordpress table to populate the javafx TableView.
In WP db I have 2 tables wp_posts & wp_postmeta and I need JOIN the table by ID (post_id in wp_postmeta) and select specific rows from wp_postmeta (not all).
For Exampe:
wp_postmeta structure post_id, meta_key, meta_value. In meta_key there is 3 rows - _yoast_wpseo_title, ._yoast_wpseo_metadesc, ._yoast_wpseo_focuskeywords
and I need this rows value from column meta_value.
My code:
ResultSet rs = connection.createStatement().executeQuery(" SELECT wp_postmeta._yoast_wpseo_title, wp_postmeta._yoast_wpseo_metadesc, wp_postmeta._yoast_wpseo_focuskeywords, wp_posts.post_title, wp_posts.post_name FROM wp_postmeta INNER JOIN wp_posts ON wp_posts.ID = wp_postmeta.post_id ");
And of course I receive error that columns _yoast_wpseo_title, _yoast_wpseo_metadesc, _yoast_wpseo_focuskeywords not found because thay are rows.
How I can do this? (I use java9, javafx, mysql jdbc). Or may be I must use PreparedStatement?
Screenshot:
Since you want to filter your query based on the content of the meta_key field, you use a WHERE clause:
SELECT wp_postmeta.meta_key, wp_postmeta.meta_value, wp_posts.post_title
FROM wp_postmeta INNER JOIN wp_posts ON wp_posts.ID = wp_postmeta.post_id
WHERE wp_postmeta.meta_key IN ('_yoast_wpseo_title', '_yoast_wpseo_metadesc', '_yoast_wpseo_focuskeywords')
You are providing a list of the meta keys you want to match. This will give (up to) three rows for each post.
If you want only one row for each post, things get more complicated (and probably aren't worth the trouble). You can use GROUP BY post_id and then study the Aggregate functions.

How to update 2 tables using one query in JPA native query?

I have 2 tables TABLE1 and TABLE2.Table1 is having name and Table2 is having email and Phone.
To get the name,email and phone,I query as below
query = entityManagerUtil.createNativeQuery("select s.Name,c.Phone1,c.Email1 from Table1 s,Table2 c where c.id= s.NodeID and s.NodeID =21")
Now my next requirement is to update name,email and phone.As these parameters are present in different tables so I am searching for single query which will update 2 tables.Unfortunately I am using sql server and there is no way to update 2 tables using single query
So I am thinking to use #Transactional and 2 queries to update 2 tables like the follow
#Transactional
public void updateDetails()
{
Query query1= entityManagerUtil.entityManager.createNativeQuery("update Table1 set Name='' where id in (select NodeID from Table 2) and NodeID=21");
Query query2= entityManagerUtil.entityManager.createNativeQuery("update Table2 set Email='' and phone1='' where NodeID in (select id from Table 2) and NodeID=21");
query1.executeUpdate();
query2.executeUpdate();
}
Is there any other better way to update 2 tables?
you can use JDBCTemplate
http://sujitpal.blogspot.com.es/2007/03/spring-jdbctemplate-and-transactions.html
It allows to do multiple queries with one connection, so you save some time instead of doing it twice.
Why don't you use Hibernate entities for that. Just load the entities associated with Table1 and table2, modify them and let the automatic dirty checking mechanism to update the tables on your behalf. That's one reason for using an ORM by the way.

"DISTINCT ON" with HQL?

I am trying to get distinct values from table application based on the column entry_id. I've managed to get this working with plain SQL:
SELECT DISTINCT ON (a.entry_id) a.* FROM application AS a
JOIN entry AS e ON e.id = a.entry_id
WHERE e.valid_until BETWEEN ? AND ?;
The problem is, I have to translate it to HQL. Is there any way to resolve it in HQL without Criteria API?
It looks like this feature has been requested a long time ago but is still unresolved.

Categories

Resources