MySQL to HQL query - mysql

How should I convert this MySQL query to HQL to retrieve some data I need?
SELECT pu.url, count(sen.content)
FROM Sentence sen JOIN ProcessedUrl pu
ON sen.PROCESSED_URL_ID=pu.url_id
GROUP BY pu.url ORDER BY 2;
In my code there is POJO ProcessedUrl which have id/url/date/set(of Sentence) fields mapped. I wanted to do something like:
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
List<ProcessedUrl> result = session.createQuery("proper HQL query", ProcessedUrl.class).getResultList();
transaction.commit();
session.close();
return result;
and then iterate over this result to print result.getUrl() & result.getSentences().size() for each url.
I know my query should return fields which are inside ProcessedUrl then how I can return some grouped query and retrieve data from it that is not kept directly inside the table? Like this count() for every url?
Thanks for help.

I have found out right HQL query so no need help anymore.
List<Object[]> result = session.createQuery("select pu.url, count(sen.content)"
+ " FROM ProcessedUrl pu"
+ " JOIN pu.sentences sen "
+ " GROUP BY pu.url "
+ " ORDER BY 2", Object[].class).getResultList();

Related

JavaFX MySQL Query only showing first result for customerId, but count shows both customers

Creating an application in which this specific function is supposed to search the MySQL database for customers with customerId's that have appointments during each specific month, and show customerId on the left column of a TableView and show number of appointments that customer has for a specific month in the right column (Count).
Focusing on December results, the code seems to only be grabbing the first result for customerId, but counts the two appointments in December for Count. Example, for December, it should show 3 & 4 for customerId on separate rows, with each having 1 for Count in December. Instead the result is 3 for customerId, and Count is 2. Below is the DAO code written, JavaFX is linked to MySQL.
I'm sure it's an issue with the SQL code section as I'm new to coding, but MySQL skills are even lesser. Thank you for any help you may have!
public static ObservableList<Report> getDecemberCustomers() {
ObservableList<Report> monthCustomers = FXCollections.observableArrayList();
try {
PreparedStatement stmt = DBConnection.conn.prepareStatement(
"SELECT MONTHNAME(`start`) AS \"month\", customerId AS \"customerId\", COUNT(*) as \"count\" "
+ "FROM appointment "
+ "WHERE MONTH(start) = 12"
);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Report monthCustomer = new Report();
monthCustomer.setMonth(rs.getString("month"));
monthCustomer.setCustomerId(rs.getInt("customerId"));
monthCustomer.setCount(rs.getInt("count"));
monthCustomers.add(monthCustomer);
}
} catch (SQLException e) {
System.out.println("SQL error: " + e.getMessage());
}
return monthCustomers;
}
Your query is missing a GROUP BY clause, so it is counting all appointments for all customers into one row, with an indeterminate customerId value. You need to GROUP BY customerId to get the appointments per customer:
PreparedStatement stmt = DBConnection.conn.prepareStatement(
"SELECT MONTHNAME(`start`) AS \"month\", customerId AS \"customerId\", COUNT(*) as \"count\" "
+ "FROM appointment "
+ "WHERE MONTH(start) = 12 "
+ "GROUP BY customerId"
);
Dependent on your MySQL version, you may also need to add month to the GROUP BY i.e. GROUP BY customerId, month.

SELECT query not passing parameters

I have an select query with inner join, and the where clause is in the second Query,
Here is the code :
static String Showplan = "SELECT * From plan_audit INNER JOIN (SELECT Du,Au From Programme_audit Where Du = '?' AND Au = '?')AS T ";
public void buttonClick(ClickEvent event) {
try{
Class.forName("com.mysql.jdbc.Driver");
Core.con = DriverManager.getConnection(Core.db,Core.dbUsername,Core.dbPassword);
PreparedStatement st;
st = Core.con.prepareStatement(Core.Showplan);
st.setString(1,select.getValue().toString());
st.setString(2,select1.getValue().toString());
ResultSet rs = st.executeQuery();
while(rs.next()){
table.addItem(new Object[]{rs.getInt(1),rs.getString(2),rs.getDate(3),rs.getString(4), rs.getString(5),rs.getString(6),rs.getString(7),rs.getString(8),rs.getDate(9),rs.getString(10),rs.getString(11),rs.getDate(12),rs.getString(13),rs.getString(14),rs.getString(15)},rs.getInt(1));
}
}catch(Exception e){
e.printStackTrace();
}
}
});
and the exception being raised is the following:
java.sql.SQLException: Parameter index out of range (1 > number of
parameters, which is 0).
Don't put single quotes after the parameter markers ?. In fact, don't do anything to them, rather let Java insert the data as it sees fit:
String sql = "SELECT * From plan_audit INNER JOIN ";
sql += "(SELECT Du, Au From Programme_audit Where Du = ? AND Au = ?) t ";
PreparedStatement st = con.prepareStatement(sql);
st.setString(1, select.getValue().toString());
st.setString(2, select1.getValue().toString());
ResultSet rs = st.executeQuery();
The whole point of prepared statements is to let Java worry about how to bring your data into the query. In this case, since you are binding strings, they would be surrounded by single quotes, but you do not need to be concerned with this.
As a side note, your query is actually doing a cross join, since you never specify a join condition. This may or may not be what you intend, but most likely you want to have some kind of join condition here.
Have you tried the parameter indexes 0 and 1 instead of 1 and 2?
st.setString(0,select.getValue().toString());
st.setString(1,select1.getValue().toString());
The single quotes are correct.

issue with checking already existing values in table

I want to check of the values in my 3 textfield already exist in my table before proceeding further in my statement but it does not work in eclipse but work in heidisql? prepareStatement and resultset are properlt initislise at the top.
I already try using ? and preStatement.setString(1, get_status_update) but it gave me the same error result.
String get_status_update = stats_status_txta.getText();
String get_username= friend_username_txtf.getText();
String get_friendname= friend_list_txta.getText();
DB_connection db_connection = new DB_connection();
try{
if(get_username.length() < 3) {
JOptionPane.showMessageDialog(statusPanel,"You need to insert a username here","Post Lodge Status Error", JOptionPane.INFORMATION_MESSAGE);
} else if (get_status_update.length() < 3) {
JOptionPane.showMessageDialog(statusPanel,"Please insert the status update you wish to like","Post Lodge Status Error", JOptionPane.INFORMATION_MESSAGE);
} else {
String sql = " SELECT sut.status_update_id, up.user_id , fd.friend_id "
+ "FROM tb_logde_status_update as tsu "
+ "INNER JOIN status_update_tb as sut ON sut.status_update_id = tsu.status_update_id "
+ "INNER JOIN user_profile as up ON tsu.user_id = up.user_id "
+ "INNER JOIN friend_details as fd ON tsu.friend_id = fd.friend_id "
+ "WHERE sut.status_update_msg='"+get_status_update+"' AND up.username='"+get_username+"' AND fd.friend_username='"+get_friendname+"' ";
preStatement = db_connection.connect().prepareStatement(sql);
res = preStatement.executeQuery();
boolean send_logde_status = false;
while (res.next()) {
if(res.getString("status_update_msg").equalsIgnoreCase(get_status_update)
&& res.getString("username").equalsIgnoreCase(get_username)
&& res.getString("friend_username").equalsIgnoreCase(get_friendname)) {
JOptionPane.showMessageDialog(statusPanel, "Status update has already been like by you, choose another one!");
send_logde_status = true;
break; // Get out of the loop. No more need for it.
// Maybe the error is around here?
}
} ...
When I use the query directly from the database query it work!
SELECT sut.status_update_id, up.user_id , fd.friend_id
FROM tb_logde_status_update as tsu
INNER JOIN status_update_tb as sut ON sut.status_update_id = tsu.status_update_id
INNER JOIN user_profile as up ON tsu.user_id = up.user_id
INNER JOIN friend_details as fd ON tsu.friend_id = fd.friend_id
WHERE sut.status_update_msg="not hallo world" AND up.username="username" AND fd.friend_username="paul";
I am inserting the exactly values from my 3 textfields. I am getting the status_update_id, user_id, friend_id when i use the query from the database but not in my action listener button
Error: Column 'status_update_msg' not found.
Maybe the parameters are not exactly the same as the ones passed in the direct query, I would suggest the following:
Log the parameters values in console
Try using trim() and/or toLowerCase() if parameter values need to be in lower case only
Also, using setXXX() methods for preparedStatement is better approach than appending parameter values to a String query.

DQL And Equivalent SQL Not Returning Same Number Of Result Set

Here is my doctrine query running code:
$queryString = "SELECT ct, count(ct.id), IDENTITY(a.service) "
. "FROM ConnectionTriple ct "
. "JOIN ct.account_connection ac "
. "JOIN Account a WITH (a = ac.account_1 OR a = ac.account_2) "
. "GROUP BY a.service, ct.property, ct.value";
$query = $em->createQuery($queryString);
//echo $query->getSQL();
$results = $query->getResult();
echo count($results);
This above code is returning 2 results(final two from below screenshot) instead of 4(expected). But, when I run the equivalent SQL(got by $query->getSQL()) on phpmyadmin, it returns expected 4 rows which is as below:
Equivalent SQL Query:
SELECT u0_.id AS id0, u0_.value AS value1, u0_.status AS status2, u0_.flag AS flag3, count(u0_.id) AS sclr4, u1_.service_id AS sclr5, u0_.property_id AS property_id6, u0_.account_connection_id AS account_connection_id7 FROM usc_connection_triple u0_ INNER JOIN usc_account_connection u2_ ON u0_.account_connection_id = u2_.id AND (u2_.status = 1) INNER JOIN usc_service_subscriber u1_ ON ((u1_.id = u2_.account_1_id OR u1_.id = u2_.account_2_id)) WHERE (u0_.status = 1) AND (u1_.status = 1) GROUP BY u1_.service_id, u0_.property_id, u0_.value
PHPMyAdmin Result:
So, I guess, there is something wrong in result to object hydration by doctrine, I guess. Anyone has any idea why this might happen/possible solution?
My Doctrine version are:
"doctrine/dbal": "2.3.2",
"doctrine/orm": "2.3.2",
Update: I am certain about the hydration issue. Because, I tried with individual column retrieving and using scalar hydration:
$results = $query->getResult(\Doctrine\ORM\Query::HYDRATE_SCALAR);
This is returning perfectly. Which is expected number of rows, 4 and data as well.
I would say this is totally normal.
As you pointed it out, doctrine (default) hydration mode would represent the result set as an object graph.
An object graph always have a root object (in your case ConnectionTriple ct).
There are 2 ct in your result set (with id 1 and 2).
Doctrine object hydrator will be smart enough to return you and array
of 2 ConnectionTriple objects, each line containing the related data.
The scalar hydrator, howerver will simply return the raw resultset, without building a graph from it.

HQL Query fails in Hibernate MySQL

I want to recuperate all rows from user table.
String queryS = "select u from user u";
System.out.println("entityManager: "+(entityManager == null));
Query query = entityManager.createQuery(queryS);
//staff
The line that throws the exception is Query query = entityManager.createQuery(queryS);
I don't know why even persistance file is ok and the table exists
The stack is:
10:36:06.693 [AWT-EventQueue-0] DEBUG org.hibernate.hql.ast.ErrorCounter - throwQueryException() : no errors
10:36:06.693 [AWT-EventQueue-0] DEBUG o.h.hql.antlr.HqlSqlBaseWalker - select << begin [level=1, statement=select]
You have to put the name of the table in the query as in the persistence file not in database.
If this:
String queryS = "select u from user u"
Is referred on table name you can't use createQuery method but createNativeQuery
If you want to use createQuery you must use in your query the entity/class mapped youe user table
Summarizing:
Case 1 (use createNativeQuery)
String queryS = "select u from user u";
Query query = entityManager.createNativeQuery(queryS);
Case 2 (use createQuery)
String queryS = "select u from " + User.class.getName() + " u";
Query query = entityManager.createNativeQuery(queryS);