Using intellij idea 2016-3.4, is it possible to inject a language based on a parameter? Consider this
#Query(nativeQuery = true, value = "select * from Foo")
List<Foo> nativeQuery();
#Query(value = "select a from Foo a")
List<Foo> hqlQuery();
The first example is a native mySql query, so I'd like to inject mySql dialect, while the second one is a hql query, where I would like to inject the hibernate query language.
Right now, if I inject a language in one of the both query strings, both change to that language injection.
Can I make idea understand the nativeQuery parameter in the #Query annotation?
Yes it's possible.
You can't to do it over Language Injection window.
But you can use language injection comments or #Language annotation. Below I inject MySQL and HTML in the same annotation using comments:
To remove comment hit Alt+Enter (OS X ⌥+Enter) and choose Un-inject Language/Reference.
Related
I currently have the query stated below. I know this works as a SQL query, but because I am using the EntityManager, from javax.persistence, it requires JPQL. And I don't know JPQL. If there is a way to rewrite this in JPQL that would be nice.
Query q = entityManager.createNativeQuery("
WITH original AS (SELECT *, COUNT(ref) as c FROM Tri WHERE triH IN :list GROUP BY ref
SELECT ref FROM original WHERE c = :amtTri");
q.setParameter("list", posTri);
q.setParameter("amtTri", posTri.size());
Actual query:
WITH original AS (SELECT *, COUNT(ref) as c FROM Tri WHERE triH IN :list GROUP BY ref
SELECT ref FROM original WHERE c = :amtTri
I am trying to do this in a Quarkus project using the Repository method, if there is a way to use that, that would also be fine
Thanks in advance!
I believe that using the EntityManager don't obligates you to use JPQL, you can also use Native Queries.
As your query looks not so simple (for me at least), I would do it using Native Queries and not JPQL. You can run Native Queries using the EntityManager from javax.persistence. This tutorial explains how you can do this.
Hi Stack I need some help please.
Im building an intentionally vulnerable local app. And I need a parameter to not have validation because the app will be for developers to test security vulnerabilities like SQL injection and XSS. I am struglling to find a way to make a query vulnerable to SQL injection using local DB JPA UserRespository but the only query it lets me is the following.
#Repository
public interface UserRespository extends CrudRepository<User,Long>{
#Query(value="SELECT * FROM USERS WHERE name = :name", nativeQuery=false)
User VulnerableQuery(String name);
}
So I cant actually trigget an SQL injection. Does anybody know any other way?
If you use a native query like this?:
#Query(value="SELECT * FROM USERS WHERE name = :?1", nativeQuery=true)
This question already has answers here:
How to replace table name with parameter value while using Spring Data JPA nativeQuery
(5 answers)
Closed 3 years ago.
I am using Hibernate and Spring data JPA to build a web project.
In Eclipse-Link we can use native query like
String tableName = "sometablename";
String query = "SELECT * FROM " +tableName +"WHERE id > 10";
In Hibernate I am using #Query annotation
#Query(value = "SELECT COUNT(r.id) as resultsCount FROM #{#resultTable} r WHERE r.customerId= :customerId AND r.is_deleted=0 AND r.is_ignored=0 ", nativeQuery = true)
Integer getResultsCount(#Param("customerId") int customerId,
#Param("resultTable") String resultTable);
I tried #{#resultTable} but this is getting replaced as a string with quote and i am getting an exception that
You have a error in your SQL Syntax
I want to use table name dynamically from params. Is it possible? And if yes, Please tell me how?
It's not possible, #org.springframework.data.jpa.repository.Query takes only jpql, you cannot pass the name of the table since it's not recognized as any entity.
It states the javadoc of Query:
/**
* Defines the JPA query to be executed when the annotated method is called.
*/
String value() default "";
The best solution would be not to pass tablename as string, but resolve it using for example inheritance (link) or rebuild your datamodel somehow. As a quick and dirty solution I would suggest creating a custom repository and using EntityManager.createNativeQuery and pass the sql there. But remember to validate the query you're composing (validate user input, use enums for table names), because it can lead to sql injection.
Your own observations actually answer your question:
I tried #{#resultTable} but this is getting replaced as a string with quote and i am getting an exception
The placeholders which are used inside the #Query query string are intended to filled with literal values. Hence, the table name ended up appearing as literal string, inside single quotes. This means that behind the scenes #Query and Spring are probably using a JDBC prepared statement. It is not possible to bind the name of the table. Allowing this would be a major security hole.
The only possible workaround here would be to concatenate your query string together, and then trying to use that string with #Query. But note that this would not be a safe option.
What you are doing is wrong, you are mixing business logic into DAO layer, i suggest you create two DAO's, each one with its own table and query, then into the business/service layer call the desired one.
#Query(value = "SELECT * FROM H4 WHERE 1")
List getResult();
Instead of the query "SELECT * FROM H4 WHERE 1" I want to put a String variable containing query generated elsewhere.
#Query, like any other annotation, uses a compile time constant to define attributes. You can't define it's value in runtime unless you plan to hack the Spring Data JPA framework.
You should use either Specifications with criteria, Query by example or JPQL to define and execute your dynamic query.
Create constants and set the value as below.
#Query(value = ApplicationConstantClass.QUERY_STRING_CONSTANT)
List getResult();
or Use EntityManager or SessionFactory of hibernate to execute dynamically generated query.
I have a spring application that should connect to an existing database and just query an entity for existence based on some attributes.
I don't want to create a #Entity class for this. But I still want to use the spring managed EntityManager etc.
When using Spring, what is the best approach to just query a select for that entity? Using em.createNamedQuery(QUERY); with String QUERY = "SELECT count(*) from my_table where username =: username AND email := email)";?
Answers from #predrag-maric and #pL4Gu33 are both correct but if you use JPA in your project (for example, Hibernate) you might consider using #NamedNativeQuery annotation as well.
More about named native queries.
simple example of native query
#PersistenceContext
EntityManager em;
public String test(Integer id)
{
Query query = em.createNativeQuery("SELECT name FROM Accounts where id=?");
query.setParameter(1,id);
return query.getSingleResult();
}
You can use this method from entitymanager. http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#createNativeQuery%28java.lang.String%29
Use em.createNativeQuery(QUERY). Also, you'll have to use positional parameters (?1) instead of named parameters (:email), because only positional parameters are supported by JPA in native queries.