while running a named query in hibernate-5 how I would make sure that it is using JPA2.1 standards - hql

while running a named query in hibernate-5 how would I make sure that it is using JPA2.1 standards(JPQL Grammer)
When running in hibernate5 it executes fine, this should fail when in JPA2.1, what/where do I need set something to use the JPA standard(JPQL Grammar).
String queryString = "from DeptEmployee where employeeNumber = :employeeNo";
Query jpaQuery = entityManager.createQuery(queryString);
this should throw an exception (for not having a "select" keyword according) when running against JPQL grammar in Hibernate-5
but should run fine without setting JPQL grammar.
I want to run using Hibernate5 engine but still want to keep the JPA implementation. btw I tried this property 'hibernate.query.jpaql_strict_compliance= true',
this didn't work.
ref: http://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/cfg/AvailableSettings.html#JPAQL_STRICT_COMPLIANCE

You can't. Because Hibernate is the underlying JPA implementation and accepts queries in HQL style (without select).
Btw. why do you want to do that?

Related

GraphQL SPQR fetches all fields on the server side

I'm new to Spring Boot and I just started using graphql-spqr for Spring Boot since it allows for easy bootstrapping of Java projects.
However, as per my understanding, GraphQL basically allows the fetching of selected fields from the database. As per the examples, I've seen, this type of selection in the graphql-spqr library happens on the client side. Is there a way to do selection both client-side and server-side so as to speed up the queries?
I've looked into EntityGraph examples for GraphQL but they are mostly implemented for complex queries that involve JOINs. However, nothing exists for simple queries like findAll(), findById() etc.
I would like to use findAll() with the server fetching only the fields as requested by the client. How can I do that?
What was said in the comments is correct: GraphQL (and hence SPQR, as it's merely a tool to hook the schema up) does not know anything about SQL, databases, JOINs or anything else. It's a communication protocol, the rest is up to you.
As for your situation, you'd have to inject the subselection into the resolver and pass it down to SQL. In the simplest case, it can look like this (in pseudo code):
public List<Book> books(#GraphQLEnvironment Set<String> fields) {
//pass the requested field names further
return database.query("SELECT " + fields + " FROM book");
}
You can inject ResolutionEnvironment using the same annotation, in case you need the full context.

Spring JPA derived delete query

I am using Spring Data rest with Spring JPA. I have one Spring JPA derived delete query that should deletes the list of items but when I am executing it and noticing the console I found that it is executing select query instead that's very strange situation I have ever come across.
#RepositoryRestResource(collectionResourceRel="revision", path="revision")
interface RevisionRepository extends JpaRepository<Revision, Long> {
List<Revision> deleteByContentId(long contentId)
}
I have even tried using Long instead of List<Revision> doesn't work and also have tried removeByContentId it is also doesn't work either and keeps executing the select query instead delete query.
when I am running this method this is what I got on my console
Hibernate: select revision0_.id as id1_2_, revision0_.body as body2_2_, revision0_.content_id as content_3_2_, revision0_.content_type as content_4_2_, revision0_.date_created as date_cre5_2_, revision0_.file_name as file_nam6_2_, revision0_.folder_id as folder_i7_2_, revision0_.force_ssl as force_ss8_2_, revision0_.is_active as is_activ9_2_, revision0_.lookup as lookup10_2_, revision0_.meta_description as meta_de11_2_, revision0_.meta_keywords as meta_ke12_2_, revision0_.meta_title as meta_ti13_2_, revision0_.nav_item as nav_ite14_2_, revision0_.nav_order as nav_ord15_2_, revision0_.regions_objects as regions16_2_, revision0_.summary as summary17_2_, revision0_.title as title18_2_, revision0_.updated_by as updated19_2_, revision0_.user_id as user_id20_2_ from revisions revision0_ where revision0_.content_id=?
does anyone having any idea why it is behaving strangely?
You need to add #Modifying annotation to your delete method. You will also need to make sure it is executed within a transaction, so you might need to add #Transactional annotation too, if you invoke this method not in a transaction.
Please see an example:
#Modifying
#Transactional
int deleteByFieldName( Long fieldValue );
In latest Spring >=5 and Spring Boot >=2.
#Transactional
int deleteByFieldname( Long fieldValue );
Works fine.
Note 1:
#Modifiyng annotation has absolutely no effect in this. It only work for #Query annotation. Without #Query, it is simply ignored.
Note 2:
In naming convention, that depends on the configured NamingStrategy, the CamelCase might be interpreted and nested entity relation or "_" in field name. So "Fieldname" and "FieldName" mean very different things.
Note 3:
Derived delete queries like this have a really nasty n+1 side effect. They ALWAYS first issue select for the rows then isses delete each row/entity one by one with separate delete stement. No way around this, except using #Query() with manual delete statement. And using #Query then requires the #Modifying for delete query.

spring for mongodb escaping parameters to avoid SQL injection

I am a new-by using spring with MongoDB.
I am using a Dao pattern which uses MongoOperations object.
As I have a lot of experience with RDBMS and JPA usually we use setParameter which also takes care for escaping and avoiding SQL injection.
I am wondering if there is such a think in spring for MongoDB. I could not find it but I might be missing something. I have to say I am still not sure if there is an SQL injection risk using Mongo.
Also, is there a way to create Named Queries in MongoDB?
Thank you all.
There is something very similar to SQL injection which is NOSQL injection.
The special characters are different but the concept is the same : the user can control/modify/corrupt the request.
Yet these databases are still potentially vulnerable to injection attacks, even if they aren't using the traditional SQL syntax. Because these NoSQL injection attacks may execute within a procedural language , rather than in the declarative SQL language, the potential impacts are greater than traditional SQL injection
There is a way to verify, here is an OWASP page that would help you to test.
The basic is to verify that your requests correctly escape ' " \ ; { } and maybe more.
It seems that spring data mongodb correctly escapes those, but I have no idea if it is completely safe.
As for named query, I think this answer is correct and they don't exists but you still have a #Query annotation if you have a repository.
And because you are using a custom repository doesn't mean you can't use a repository interface too, Spring data allows you to have an implementation of the repostiroy without implementing it, see here.
There is no such thing as SQL injection in Mongo, since Mongo does not use SQL language at all.
There is no concept of named queries in Spring Data MongoDB, instead you use annotate your repository methods with #Query:
public interface PersonRepository extends MongoRepository<Person, String>
#Query(value="{ 'firstname' : ?0 }", fields="{ 'firstname' : 1, 'lastname' : 1}")
List<Person> findByThePersonsFirstname(String firstname);
}

spring transaction of JdbcTemplate/HibernateTemplate and HibernateDaoSupport/JdbcDaoSupport

How transaction is controlled while using JdbcTemplate/HibernateTemplateand HibernateDaoSupport/JdbcDaoSupport? I used to check source code and didn't find where the transaction is controlled by JdbcTemplate/HibernateTemplate and HibernateDaoSupport/JdbcDaoSupport.
And In source code HibernateDaoSupport/JdbcDaoSupport is using JdbcTemplate/HibernateTemplate, what's the role of HibernateDaoSupport/JdbcDaoSupport and what's the role of JdbcTemplate/HibernateTemplate?
Why do we use JdbcTemplate/HibernateTemplate and HibernateDaoSupport/JdbcDaoSupport? It seems all sample code is using them. What should I use if I don't want to use them, such as only using spring + hibernate?
If I'm using JdbcTemplate/HibernateTemplate and HibernateDaoSupport/JdbcDaoSupport, do I still need to config transaction proxy in xml? If I still need to config transaction proxy in xml, it means it's ok for me to put both getHibernateTemplate().saveOrUpdate(user)and getHibernateTemplate().saveOrUpdate(order) together, and they're invoked in the same transaction, is this right?
First off all please forget about HibernateTemplate and HibernateDaoSupport these classes should be considered deprecated since the release of hibernate 3.0.1 (which was somewhere in 2006!). You should be creating daos/repositories based on a plain hibernate API, as explained in the Spring Reference Guide. (The same goes for JpaTemplate and JpaDaoSupport).
JdbcTemplate (and all other *Template classes) intend is to make it easier to work with the underlying technology. Once upon a time this was also needed for Hibernate (< 3.0.1), now it isn't.
JdbcTemplate makes it easier to work with plain JDBC code. You don't have to get a connection, create a (Prepared)Statement, add the parameters, execute the query, iterate over the resultset and convert the ResultSet. With the JdbcTemplate much of this is hidden and most of it can be written in 1 to 3 lines of code, whereas plain JDBC would require a lot more.
The *Support classes make it easier to gain access to a template but aren't a must to use. Creating a JdbcTemplate is quite easy and you don't really need to extend JdbcDaoSupport. But you can if you want. For more information a lot is explained in the reference guide.

Java Spring, JPA - like expression with wildcard

I am struggling with creation of JPQL statement using Like expression in Java Spring application. My aim is to implement simple case insensitive search function.
My code, which should return a list of companies containing a keyWord in their name looks like this:
List<Company> companies = em.createQuery("select cmp from JI_COMPANIES as companies where UPPER(cmp.name) LIKE :keyWord", Company.class)
.setParameter("keyWord","%" + keyWord.toUpperCase() + "%").getResultList();
return companies;
However, this query only works when my keyWord matches the name of company (Like statement is not used).
When testing the function above, I see in my console message from Hibernate:
Hibernate: select ... /* all my parameters */ ... where company0_.CMPN_NAME=?
It seems that my query is translated to cmpn_name='name' instead of using like expression.
You can look about Hibernate batch processing best pratices and Stateless session.
It was my fault due to not understanding how Spring Data JPA library works.
I have tried to create a custom implementation of myCompanyRepository (myCompanyRepository extends JpaRepository, CompanyRepositoryCustom).
The code which I mentioned above was located in my CompanyRepositoryCustomImpl class which implements CompanyRepositoryCustom interface. However I used method name "findCompaniesByName(String name)". JPA automatically creates a query from this method name and my implementation is not used.
Here is the link for Spring Data JPA reference

Resources