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);
}
Related
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.
Yesterday I've got access to the new project in my company and I have found this
public List<User> findNotActiveUsers() {
return this.userRepository.findAll().splititerator()
.filter(u -> u.isActive())
.collect(Collect.toList());
}
Is this a good way to find all the active users? Or should it be done in a repository like this?
public interface UserRepository extends JpaRepository<Long, User> {
#Query("SELECT user FROM User user WHERE user.active IS TRUE")
List<User> findActiveUsers();
}
And If first solution is correct what about performance?
Firstly, both options fulfill the requirement.
However, the option 2 makes more sense to filter the data at query level rather than at Java level. I believe the performance would be better on the second option though I don't have any data to backup this statement. I have commented about the performance based on my experience.
You can also consider whether Cache (#Cacheable) can be used. It purely depends on the use case i.e. how frequently the User entity is changed and how frequently you would like to refresh the cache.
One disadvantage of using native query is that currently Spring JPA doesn't support execution of dynamic sorting for native queries.
Please refer the similar question discussed in the below link though it is very much related to Hibernate. Clearly, the option 3 is preferred (i.e. #Query approach).
Spring Data Repository with ORM, EntityManager, #Query, what is the most elegant way to deal with custom SQL queries?
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.
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
Spring's JdbcTemplate abstraction provides a lot of functionality, but can it be used in such a way that provides protection from SQL injection attacks?
For example, like the kind of protection you would get using PreparedStatement with properly defined parameterization.
It most certainly does. This example is straight from the Spring 3.0 docs (but is the same in 2.*):
String lastName = this.jdbcTemplate.queryForObject(
"select last_name from t_actor where id = ?",
String.class, 1212L);
As you can see, it strongly favors prepared statements (which it must be using behind the scenes for you): you specify the parameters with placeholders (?) and supply an array of objects to fill into the parameters. (The last parameter is the type of the expected result, but that's not very relevant for this question.)
You can also use a NamedParameterJdbcTemplate and supply the parameters in a Map, which is perhaps less efficient but definitely more mnemonic.