getting Hibernate error when using DBMS_RANDOM.value - oracle

I would like to achieve same result as the below query using Hibernate SQL, i.e., I would like to get two random records from the table whose ID is not equal to 300. I am using Hibernate 4.1 and Oracle 11g. I ran the below query on Toad and it gives 2 random records. But, when I try to run the HQL, there is error to do with the usage of "DBMS_RANDOM.value".
SELECT * FROM
( SELECT *
FROM table
where ID != '300'
AND q_ID=125
ORDER BY DBMS_RANDOM.value
)WHERE rownum < 3
;
I tried creating criteria and query, but both give Hibernate errors:
Hibernate Message: Invalid path: 'DBMS_RANDOM.RANDOM' [from com.model.table tab where tab.ID != '33092' ORDER BY DBMS_RANDOM.RANDOM]
and my actual hibernate query is:
Query query = session.createQuery("from table tab where tab.ID != '" +agrmId+"' ORDER BY DBMS_RANDOM.RANDOM").setMaxResults(2);
I also tried ORDER BY rand() and that gives an Oracle error.
Thank you for any help.

I solved the problem by adding a property tag in the hibernate mapping file:
<property name="constVal" formula="DBMS_RANDOM.RANDOM" type="long"/>
and then, in the POJO class, I added a variable with getter and setter methods:
private long constVal;
then, in the DAO class, I added the following query:
Criteria crit1 = session.createCriteria(table.class);
crit1.add(Restrictions.ne("id",300));
crit1.add(Restrictions.eq("quesId",125));
crit1.addOrder(Order.asc("constVal"));
crit1.setMaxResults(2);
and that solved it.

Related

Oracle not using index, Entity Framework & Devart DotConnect for oracle

The table in question has ~30mio records. Using Entity Framework I write a LINQ Query like this:
dbContext.MyTable.FirstOrDefault(t => t.Col3 == "BQJCRHHNABKAKU-KBQPJGBKSA-N");
Devart DotConnect for Oracle generates this:
SELECT
Extent1.COL1,
Extent1.COL2,
Extent1.COL3
FROM MY_TABLE Extent1
WHERE (Extent1.COL3 = :p__linq__0) OR ((Extent1.COL3 IS NULL) AND (:p__linq__0 IS NULL))
FETCH FIRST 1 ROWS ONLY
The query takes about four minutes, obviously a full table scan.
However, handcrafting this SQL:
SELECT
Extent1.COL1,
Extent1.COL2,
Extent1.COL3
FROM MY_TABLE Extent1
WHERE Extent1.COL3 = :p__linq__0
FETCH FIRST 1 ROWS ONLY
returns the expected match in 200ms.
Question: Why is it so? I would expect the query optimizer to note that the right part is false if the parameter is not null, so why doesn't the first query hit the index?
Please set UseCSharpNullComparisonBehavior=false explicitly:
var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;
config.QueryOptions.UseCSharpNullComparisonBehavior = false;
If this doesn't help, send us a small test project with the corresponding DDL script so that we can investigate the issue.

spring jpa handling null value in max query

I'm trying to select a sequence id from the database using this query:
#Query("select max(pi.sequence) + 1 from ProductImage pi where pi.product = :product")
int nextSequenceForProduct(#Param("product")Product product);
It works well except when there's no values in the table, it throws some type of null value exception from the JPA code.
Is there a way to handle null values in spring jpa? For example something like this SQL:
select ifnull(max(pi.sequence),1) from ....
you can use nvl() function and change the query to native query or named native query to avoid the exception
#NativeQuery("select nvl(max(pi.sequence),0) + 1 from ProductImage pi where pi.product = :product")

Issue with selecting max id rows using criteria query / hibernate query?

I am unable to select the rows where TestId is max for respective student, I wrote the code as follows which does not get the required output. my code is as follows,
Criteria c = sessionFactory.getCurrentSession().createCriteria(student.class).setProjection(Projections.projectionList().add(Projections.property("answer"),"answer"));
c.add(Restrictions.eq("surveyId",send_Survey));
//c.add(Restrictions.eq("testId", "1" ));
//c.setProjection(Projection.max("testId"));
c.addOrder(Order.desc("testId"));
c.add(Restrictions.eq("questionid",FinalQuestionsOne));
List<String> age=c.list();
My table structure is as follows,
I need the following output. select the answer column for max TestId's. How can I get the output using criteria query
So I think what you're trying to get can be achievedd by the following sql:
SELECT TestId, MAX(answer) WHERE questionId = 1 GROUP BY TestId;
You should be able to achieve this with the following Hibernate:
sessionFactory.getCurrentSession().createCriteria(student.class).setProjection(Projections.projectionList()
.add(Projections.property("TestId"), "TestId")
.add(Projections.groupProperty("TestId"))
.add(Projections.max("answer")));

How to write the following MYSQL query in criteria query and hibernate query?

How can I write the criteria query and hibernate query for the following MySQL query
SELECT * FROM (SELECT * FROM outdatadetail where algorithmno="a0025_d2" and stringno=01 ORDER BY testid desc) sub_query GROUP BY subjectid;
Any suggestions.
String sql = "SELECT * FROM (SELECT * FROM outdatadetail where algorithmno='a0025_d2' and stringno=01 ORDER BY testid desc) sub_query GROUP BY subjectid;";
Session session = getSession().getSessionFactory().getCurrentSession();
Query query = session.createSQLQuery(sql);
As far as I understand after reading the documentation and looking at examples you don't need a sub-query to do what you are trying to.
Basically you write 1 query and set a projection to do the grouping.
Criteria query = currentSession.createCriteria(OutDataDetail.class);
query.setProjection(Projections.groupProperty("subjectid").as("subjectid"));
query.add(Restrictions.eq("algorithmno", "a0025_d2"));
query.add(Restrictions.eq("stringno", "01"));
query.addOrder(Order.desc("testid"));
return query.list();
The Criteria API by itself is fairly useful. But its real power comes when you start using classes like Projection, Subqueries, Order etc. in conjunction with your Criteria.
If you want to use the Criteria API with a sub-query you can do the following:
DetachedCriteria subquery = currentSession.createCriteria(OutDataDetail.class);
subquery.add(Restrictions.eq("algorithmno", "a0025_d2"));
subquery.add(Restrictions.eq("stringno", "01"));
subquery.addOrder(Order.desc("testid"));
Criteria query = currentSession.createCriteria(OutDataDetail.class);
query.setProjection(Projections.groupProperty("subjectid").as("subjectid"));
query.add(Subqueries.exists(subquery);
return query.list();
Both implementations should return a list of OutDataDetail objects (assuming that's the object you are working with).
DISCLAIMER: I have not tried any of this. It may be that this will not work for you. This answer is written based on my knowledge of working with the Criteria API and its associated classes in the past, and the Hibernate 4.1 Manual. You can see the manual section on Projections and grouping here.

Set array of values to SQL query

I'm using JDBC, I have to set array of values to a single column,
I know it works in Hibernate and Ibatis but it seems to be hard to get it working Pure JDBC sql.
I have an array of String values
names[] = new String[]{"A","B","C"};
and a Query like
select * from emp where name in(?)
I tried pstmt.setObject(1,names), it is not working..
This is not supported in pure JDBC. You have to generate a query so that the in clause contains one placeholder for each element of the array.
Spring's JDBC helper classes support named parameters and what you want to do.
This will work with the following Syntax:
"SELECT * FROM emp WHERE name IN ( SELECT column_value FROM TABLE( ? ) )"
pmst.setArray( 1, conn.createArrayOf( "VARCHAR", names ) );

Resources