Filter entities in spring repository - spring

It is possible to apply a filter to results with annotations instead of extending method name?
For instance:
#Repository
public interface JobRepository extends JpaRepository<Job, Long> {
List<Job> findAllByUserAndEnabledIsTrue(User u);
}
Here I apply filter 'enabled == true'. But assume we have a lot of methods. Writing them with extended names is inconvenient. Could I apply this filter to whole repository?
I found
#FilterDef but I don't know how to use and also if spring support this annotation.

As far as I know Spring Data JPA is not Hibernate dependent, and it can work with any JPA implementation. Hibernate's #Filters is not a JPA standard, so the simple answer is no! Spring JPA does not support #Filters.
But you can apply #Filters using AOP, and simply applying aspects on your repository methods.
By the way I believe the better solution is to have hand written queries using Spring Data JPA's #Query annotation. Because this way you can name methods after their context meaning, and not about their internal implementation.
For example you can name your method findActiveJobsForUser which could be more meaningful and readable.

Related

How can I check QueryHint work or not?

Spring Data JPA allows placing #QueryHints annotation on the interface method and can be applied to the methods annotated with #Query and without such.
#QueryHints(#javax.persistence.QueryHint(name="org.hibernate.fetchSize", value="50"))
List<Foo> findAll();
How can I check know for sure that hint was honored?

DataRepository and mybatis support

I have followed the guide react-js-and-spring-data-rest.
https://spring.io/blog/2015/10/28/react-js-and-spring-data-rest-part-5-security
This tutorial use JPA hibernate, I do really like the React/Api design, but I don't wan't to use JPA hibernate DAO, I would like to use Mybatis.
Is there a way to use spring DataRepository with mybatis ?
As far as I know there is not possible that way. Of course, you can use MyBatis-Spring-Boot-Starter integration which is not far different from Spring Data Repositories. It's not simply than DataRepository can be but not to more... For example one mapper should be:
#Mapper
public interface CityMapper {
#Select("SELECT * FROM CITY WHERE state = #{state}")
City findByState(#Param("state") String state);
}
Then you can inject it as a Bean Repository without implement:
#Autowired
private CityMapper cityMapper;
Unfortunately, you should do all Crud Operations in the entities you need... this could be tedious, so in de Data Repositories of Spring Data is not need.
The examples are in MyBatis Reference Documentation, and is much more explained than here.

Spring Data MongoDB: Specifying a hint on a Spring Data Repository find method

I am implementing a Spring Data Repository and having my repository extend the MongoRepository. I am looking for a way to specify a hint on my findBy methods so I can be control. I have seen several times when a non-optimal index would be picked as the winning plan.
This is what my repository looks like right now:
public interface AccountRepository extends MongoRepository<Account, ObjectId> {
#Meta(maxExcecutionTime = 60000L, comment = "Comment" )
public List<Account> findByUserIdAndBrandId(Long userId, Long brandId);
}
I researched a bunch and found that the JPARepository from spring data supports the #QueryHint annotation but I do not believe that annotation is supported for MongoDb. Is there a similar annotation I can specify on top of my findBy method to specify the hint?
MongoTemplate allows to specify a hint, however, I have a ton of findBy methods and I would hate to add an implementation underneath just to specify a hint.

Applying #PostFilter annotation to a generic Spring Data Jpa repository method

I want to use the #PostFilter annotation on a Spring Data Jpa repository generic method (such as a findAll) as follows:
#PostFilter("filterObject.isActivated()==true")
public List<Advertisement> findAll();
How can I do that bearing in mind the those methods are provided "automagically" by Spring Data Jpa and are therefore not exposed in the application code?
Yes, you can add a #PostFilter to any method provided by a Spring Data Repository. Just override existing method findAll() and add your #PostFilter annotation as depicted in your example. Don't forget to add to your configuration where your repositories are defined
<global-method-security pre-post-annotations="enabled" />
or in a java based configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
respectively.
Keep in mind. This works just for collections and arrays. For every other return type like Page you get an IllegalArgumentException. See DefaultMethodSecurityExpressionHandler#filter for implementation details.

JPA and DAO - what's the standard approach?

I'm developing my first app with JPA/Hibernate and Spring. My first attempt at a DAO class looks like this:
#Repository(value = "userDao")
public class UserDaoJpa implements UserDao {
#PersistenceContext
private EntityManager em;
public User getUser(Long id) {
return em.find(User.class, id);
}
public List getUsers() {
Query query = em.createQuery("select e from User e");
return query.getResultList();
}
}
I also found some examples using JpaDaoSupport and JpaTemplate. Which design do you prefer? Is there anything wrong with my example?
I'd say your approach looks totally sound. Personally I don't use JpaDaoSupport or JpaTemplate because you can do everything you need with the EntityManager and Criteria Queries.
Quote from the JavaDoc of JpaTemplate:
JpaTemplate mainly exists as a sibling of JdoTemplate and HibernateTemplate, offering the same style for people used to it. For newly started projects, consider adopting the standard JPA style of coding data access objects instead, based on a "shared EntityManager" reference injected via a Spring bean definition or the JPA PersistenceContext annotation.
I prefer the template-less approach (i.e. your current approach) because
it's less invasive, you don't tie DAOs to Spring
templates don't offer much value with APIs that use unchecked exceptions
And this is the Spring recommendation, as summarized in the blog post "So should you still use Spring's HibernateTemplate and/or JpaTemplate??" and the official javadoc:
The real question is: which approach to choose??
(...)
So in short (as the JavaDoc for
HibernateTemplate and
JpaTemplate already mention)
I'd recommend you to start using the
Session and/or EntityManager API
directly if you're starting to use
Hibernate or JPA respectively on a new
project–remember: Spring tries to be
non-invasive, this is another great
example!
I, personally, prefer your approach - inject EntityManager and use it directly. But JpaTemplate is also a good option. I don't like it, because adds yet another, unnecessary layer of abstraction.
I don't know if there's a "standard" approach.
If you're using JPA, you have your choice of implementations: Hibernate, TopLink, etc.
If you deploy to Google App Engine, you'll use JPA talking to BigTable.
So if your objectives are to maximize portability, stick with the JPA standard, and not tie yourself to a particular implementation like Hibernate, make sure that your DAOs only use JPA constructs.

Resources