I am trying to create Repository with L2 cache with minimal setting. My database is postgresql.
I start with spring-boot-sample-data-jpa-archetype project using maven.
I have removed the HSQL and create a DataSource bean to connect to postgresql.
Also use ddl to create schema and imported the initial script data.
I have also added the #Cacheable to my entities.
Then I use unit test to query an entity 10 times using repository. It took 1~49ms. So that leaves me two questions.
Does repository benefits from L1 cache? how do I know if I am hitting the cache or data source?
How to enable L2 cache? does Spring data has its own implementation?
After some testing and the help from #dunni, I will answer my own question.
Spring uses Hibernate as an implementation of JPA. Spring data provides some wrapper over Hibernate. Also need to choose a caching implementation.
To enable L2 cache, add these properties to your project.
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
also add these dependencies:
hibernate-ehcache
Then, add #Cacheable(true) to your entity model class.
Extends a repository interface, Spring will generate the implementation using naming convention. For example
#QueryHints({#QueryHint(name="org.hibernate.cacheable", value="true")})
Entity findByName(String name)
You can also implement the interface. But that will require adding a hint to your query object to activate L2 cache.
query.setHint("org.hibernate.cacheable", true);
To verify the cache is working, you can use the following properties to see if the SQL has been executed.
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
Related
I have a service with spring data jpa which uses multiple datasource. One of the datasource is used as the main storage and Entity is used there and repositories are described. Other datasources are used simply to call stored procedures and functions.
Can you please tell me if I can somehow create a spring data jpa repository for datasource without an entity and use the #Procedure annotations to force the function to call the stored procedure I need?
I read about https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations and just wrote my repository implementation. Looking for alternative, more convenient use cases for the spring data jpa api.
You need to use some entity as JPA is domain driven, refer Any way to use the `#Procedure` annotation without an entity?
and
Using Spring #Procedure to call StoredProcedure without binding to a table
In my opinion, you should use Just use JDBC template.
The problem is how to implement tracking of data changes on e.g. master detail tables i.e. two entities in one to many relationship in Spring Boot/Spring Data.
After storing data, to be able to get the master entity with its details at specific version, and to have functionality to revert it to specific version.
You can use Hibernate Envers to audit and version your persistence entities changes.
The Envers project aims to enable easy auditing of persistent
classes. All that you have to do is annotate your persistent class or
some of its properties, that you want to audit, with #Audited. For
each audited entity, a table will be created, which will hold the
history of changes made to the entity. You can then retrieve and query
historical data without much effort.
Similarly to Subversion, the library has a concept of revisions.
Basically, one transaction is one revision (unless the transaction
didn't modify any audited entities). As the revisions are global,
having a revision number, you can query for various entities at that
revision, retrieving a (partial) view of the database at that
revision. You can find a revision number having a date, and the other
way round, you can get the date at which a revision was commited.
The library works with Hibernate and requires Hibernate Annotations or
Entity Manager. For the auditing to work properly, the entities must
have immutable unique identifiers (primary keys). You can use Envers
wherever Hibernate works: standalone, inside JBoss AS, with JBoss Seam
or Spring. source
You can query for historic data in a way similar to querying data via
the Hibernate criteria API. The audit history of an entity can be
accessed using the AuditReader interface, which can be obtained with
an open EntityManager or Session via the AuditReaderFactory. source
With Hibernate Envers you can record your data changes and then access it whether using your persistence context or SQL in order to apply your version changes using the provide revision id. With it you've the 80% of the task done.
Check this tutorials
Setting up Hibernate Envers with Spring Boot
Auditing with JPA, Hibernate, and Spring Data JPA
Hibernate Envers: Simple Implementations
If you use JPA, object auditing frameworks like hibernate envers or javers might help
I'm curious what is the difference between the spring-jdbc (what I missing in the newest spring release) and spring-data-jdbc.
Is there a difference or just a renaming (in the repositories I don't see this)?
And is there somewhere described what are the supported targets(DB/JDBC specs/JDK) of the versions?
e.g. for the plain JDBC from oracle I can see that information here:
http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#01_03_1
(e.g.: JDBC Spec 4.1 in ojdbc7.jar on Java7/Java8 on Oracle DB 12.1/12cR1)
But I miss that for spring-jdbc - where do I find that information?
spring-jdbc
The docs for spring-jdbc are basically here:
https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html
Though it doesn't specifically point you to the Spring project spring-jdbc. This project just provides all of the Spring abstractions over the plain JDBC DataSource that you can use with the Spring Framework. For example, Spring's DataSources which nicely hook into Spring's Transaction management capabilities, like the #Transactional annotation.
Also, the JdbcTemplate is part of this module, which allows you to execute SQL statements and extract objects from ResultSets without dealing with exception handling or the nasty details of properly closing statements, connections and the like.
spring-data-jdbc
spring-data-jdbc, on the other hand, provides the Spring Data abstraction over spring-jdbc. That is, you can create a Spring Data CrudRepository and a simple "entity" (not a JPA entity!) and, as Spring Data does, it will create your queries for you without you having to write native CRUD queries over JDBC, as in this example on the spring-data-examples git repo.
Using the referenced example as a demonstration:
interface CategoryRepository extends CrudRepository<Category, Long> {}
The above code is all you could need (using introspection on the Category object name as the source for the table name (based on a NamingStrategy) and it's properties as columns, again similar to JPA, but not using JPA.
Rather than writing your own like so:
#Repository
public class CategoryRepository {
public void create(Category category) {
jdbcTemplate.execute("insert...");
}
// The rest of my other CRUD operations
}
I am working on a spring batch solution and planning to use MongoDB as a job repository. I am looking for a references on this implementation but could not get any references. Then I was checking the spring-batch-core-3.0.7.RELEASE.jar, there I could not able to see MongoDB schema. Does this mean Spring batch does not support MongoDB as job repository?
That is correct. Mongo is not a suitable data store for the job repository due to the transactionality requirements of the job repository. The data store must be ACID compliant in order to be used which is why we have focused our efforts on relational databases for the repository implementation to date.
There is a recent (v1.0.0 in 2021-11-02) project to handle that, it's not managed by Spring team :
https://github.com/europeana/spring-batch-mongo
This library provides MongoDB JobRepository support for Spring Batch.
On official Spring side, there is this opened issue :
https://github.com/spring-projects/spring-batch/issues/877
I'm familiar with how to make Spring handle multiple datasources dynamically via multiple persistence-units and multiple entityManagerFactoryBean implementations but what I'm struggling with is how to have a MySQL dialect and a DynamoDB dialect from within the same spring configuration, via spring-config xml files.
The work pattern is as follows:
[data POJO in, from some endpoint] -> Persist POJO into DynamoDB, retrieving the UUID of that object (business key as field on POJO) -> Persist UUID as a compound key (no referential integrity, it's just another column) into MySQL Database [with other related mapped entities].
I'm struggling with quite how on earth to go about adding the DynamoDB instance into the Spring configuration files to achieve this.
For what it's worth, the related repositories are going to be in separate packages.
Any starters for 10 would be gratefully received! I've done some searching but all DynamoDB mapper frameworks seem to be at a much higher level - have I missed something here? I've been looking at Spring-Data DynamoDB but still can't make the link between the configuration file and Dynamo.
Thanks in advance,
A.
========= UPDATE IN THINKING =========
I think I've gone about this the wrong way. From digging around the samples a lot more, doing a local integration test [pure dynamodb], I don't think it's possible to use DynamoDB as part of an EntityManager Factory implementation: to that end, I think I'm going to have to "create" my own repository implementations that call out to the mapper and AWS connection helper classes etc. for Dynamo, rather than using any of the JPA spring-provided code.
Unless anyone can recommend/suggest otherwise?
Question closed - after much investiation the only real way to do it is to introduce ones own interpretation of a repository and DAO-based implementation.
There is one interesting project, however, Spring Data Dynamodb. Looks interesting but not quite ready for Enterprise Production release.