Spring Data #Query from application.properties - spring-data

How can I take a query from application.properties in Spring Data?
OrderRepository.java:
#Repository
public interface OrderRepository extends CrudRepository<Order, UUID> {
#Query("#{app.queryExample}") // TODO the query should come from application.properties
Set<Order> findByExampleQuery();
}
application.properties:
app.queryExample=select o from Order o

Related

Spring Data Jpa Query methods are not invoking the repositoryBaseClass

I have a repository base class as defined below.
#NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
}
public class BaseRepositoryImpl<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> {
public BaseRepositoryImpl(JpaEntityInformation<T, ?> entityInfo, EntityManager entityMgr) {
super(entityInfo, entityMgr);
}
// ...
}
#Configuration
#EnableJpaRepositories(basePackages = "org.example",
repositoryBaseClass = BaseRepositoryImpl.class)
public class BaseConfig {
// additional JPA Configuration
}
I have defined a business repository class and a query method as seen below.
#Repository
public interface CarRepository extends BaseRepository<Car, Long> {
#Query("SELECT c FROM Car c Where active = 1")
List<Car> findAllActiveCars();
}
I have a test class which invokes the findAllActiveCars(). I am getting the expected results. But, that query method is not invoking any of the methods in BaseRepository class. How to customize the return values of the query methods?
You didn't show the methods that you did implement, so it is not clear why they don't get called, but since you want to decrypt entity fields, consider listening to JPAs entity lifecycle events. #PostLoad should be able to do the trick.
https://docs.jboss.org/hibernate/core/4.0/hem/en-US/html/listeners.html

Spring Data Rest with Cache

I was learning Spring Data Rest but I didn't find how to use Cache in Spring Data Rest.
How can i use Cache with Spring Data Rest's curd/page .
Or should I use JPA+Cache and ignore Spring Data Rest?
If I misunderstanding anything please remind me.
best regard
You can try the following approach:
1) Override your repos methods findById and findAll, make them Cacheable:
public interface MyEntityRepo extends JpaRepository<MyEntity, Long> {
#Cacheable("myEntities")
#Override
Optional<MyEntity> findById(Long id);
#Cacheable("pagedMyEntities")
#Override
Page<MyEntity> findAll(Pageable pageable);
}
2) Create a RepositoryEventHandler to evict your caches:
#RepositoryEventHandler
public class MyEntityEventHandler {
private final CacheManager cacheManager;
public MyEntityEventHandler(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
#HandleAfterCreate
#HandleAfterSave
#HandleAfterDelete
public void handleCachesEviction(MyEntity entity) {
Optional.ofNullable(cacheManager.getCache("myEntities"))
.ifPresent(c -> c.evict(entity.getId()));
Optional.ofNullable(cacheManager.getCache("pagedMyEntities"))
.ifPresent(c -> c.clear());
}
}
3) And of course create a cache manager bean, for example:
#EnableCaching
#SpringBootApplication
public class Application {
#Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
}

possible to extend SimpleMongoRepository

My current spring boot mongo configuration looks like following
#Configuration
#EnableMongoRepositories(Constants.SCAN_PACKAGE)
#Import(value = MongoAutoConfiguration.class)
public class MongoDatabaseConfiguration {
#Bean
public ValidatingMongoEventListener validatingMongoEventListener() {
return new ValidatingMongoEventListener(validator());
}
#Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
}
Now i would like to extend the class SimpleMongoRepository which seems to be the default implementation of MongoRepository. What configuration i have to do so my CustomMongoRepository extends SimpleMongoRepository is picked up instead of SimpleMongoRepository which is default shipped.
It's described in the Reference Documentation
You basically extend SimpleMongoRepository and specify that class in the #EnableMongoRepositories annotation as repositoryBaseClass.

How to configure collections other than fs.files fs.chunks in GridFsTemplate in MongoDB

GridFsTemplate insertes data in collections:fs.files and fs.chunks.
Is there any way to make GridFsTemplate use my own collections?
e.g. In my project, I need to dump all files in attachments.files and attachments.chunks.
I am able to do it using just GridFs like this:
DB mongoDB = mongoDbFactory.getDb();
GridFS fileStore = new GridFS(mongoDB, "attachment");
but I would like to do it by #autowire GridFsTemplate, perform operations like gridFsTemplate.store(file, filename), and it should dump data in my own collections.
To be able to Autowire it with a default Bucket, you can define a Bean for it in Mongo Client Configuration. It goes something like this:
Create a configuration class->
#Configuration
public class MongoConnectionConfig extends AbstractMongoClientConfiguration {
//store this in application.properties file 'mongo.file-system-bucket.attachment=attachment'
#Value("${mongo.file-system-bucket.attachment}")
private String bucketAttachment;
//store this in application.properties file 'mongo.file-system-bucket.image=image'
#Value("${mongo.file-system-bucket.image}")
private String bucketImage;
#Autowired
private MappingMongoConverter mongoConverter;
#Bean(name = "gridFsTemplateAttachments")
public GridFsTemplate gridFsTemplate() throws Exception {
return new GridFsTemplate(mongoDbFactory(), mongoConverter, bucketAttachment);
}
#Bean(name = "gridFsTemplateImages")
public GridFsTemplate gridFsTemplate() throws Exception {
return new GridFsTemplate(mongoDbFactory(), mongoConverter, bucketImage);
}
}
Now to use these Beans you can Autowire them in your DAO and work with different buckets as per your requirements.
Eg. ->
#Repository
public class AssetTransactionsDAO implements AssetTransactionsInterface {
#Autowired
private GridFsTemplate gridFsTemplateImages;
#Autowired
private GridFsTemplate gridFsTemplateAttachments;
#Override
public String insertAttachment(AttachementModel attachment){
//do your stuff gridFsTemplateAttachments.store(.....)
return "";
}
}

Mongo custom repository autowired is null

I try to autowire my custom mongo repository (and it seems the constructor is executed) but still the result is null
I've looked at some similar questions
Spring Data Neo4j - #Autowired Repository == null
and
spring data mongo repository is null
but I still don't know how to solve this.
public class TestRepo {
#Autowired
PersonRepository repository;
public void find(String name)
{
System.out.println(repository.findByName(name));
}
}
config
<mongo:repositories base-package="com.yyyy.zzz" />
PersonRepository
public interface PersonRepository extends Repository<Person, BigInteger> {
#Query("{name : ?0}")
public Person findByName(String name);
}
Implementation
public class PersonRepositoryImpl implements PersonRepository{
PersonRepositoryImpl()
{
System.out.println("constructing");
}
public Person findByName(String name) {
...
}
}
if I get the repository bean directly from context it works
Your repository setup looks suspicious. To execute query methods, you don't need to provide an implementation at all. I suspect in your current setup the custom implementation you have in PersonRepositoryImpl "overrides" the query method and thus will be preferred on execution.
If you simply drop your implementation class, Spring Data will automatically execute the query for you on invocation.
Generally speaking, custom implementation classes are only needed for functionality you cannot get through other means (query methods, Querydsl intergration etc.).