Spring Data Multiple tables Generic repository - spring

My application has an unknown number of tables that conform to one of two structures. Standard and Outsized. Unfortunately, it's not until runtime that I know how many tables are in the schema that corresponds to standard or outsized?
I've created generic Standard and Outsized repositories like so
public interface StandardTableRepository<T extends AbstractStandardTable>
extends CrudRepository<T, Long> {}
but because the schema isn't static I can't create the Entities until runtime?
I understand JPA doesn't really cater for non-static schemas but is there any way that I could expose a generic restful service that would allow me to instantiate this repository at runtime perhaps using a table name supplied in the QueryParams?

Related

Spring Data JDBC custom query parameter converter

I am trying to add a custom query to a Spring Data JDBC CrudRepository to allow finding entities by an alternate natural key. The entity has an ID which is in this case a Long, and a natural key, that is of type Reference (underlying type is UUID).
I have created and registered custom converters from Reference to UUID and vice versa, and would like to use them when finding entities by Reference. Conversion works when fetching and storing entities to and from the database (Postgres 12.2).
What I couldn't manage to do is to define a custom method that finds the entity by its Reference.
This is similar to my situation:
public interface OrderRepository implements CrudRepository<Order, Long> {
#Query("select o from Order o where o.reference = :reference")
Optional<Order> findByReference(#Param("reference") Order.Reference reference);
}
Can this be done in this way? I am using the latest version of Spring Data JDBC (1.1.6).
I would like to avoid having a query that accepts the underlying type (UUID in this case).
If this can't be done by using a custom Query, what are the available options?
I have considered maybe using MyBatis with Spring Data JDBC?
This is a known issue, which got implemented with 2.0 M3 which is available from Springs Milestone repository. Please give it a try.
Note: 2.0 M3 introduces Dialect but proper automatic detection only comes with 2.0 RC1` which is due to be released today 2020-03-31. You may wait for that to save you some headaches

Can we make Spring JPA Specifications work with EntityGraph?

I am implementing a dynamic query logic using JPA specifications on an entity. The entity is having multiple relations with other entities. I am running into the issue of generating too many queries while executing JPA specifications.
Is there a way to combine JPA specifications findAll(specification, page) with EntityGraph so that we can one query generated while executing the same?
Yes it is absolutely possible to pass EntityGraph using EntityGraphJpaSpecificationExecutor
#Repository
public interface UserRepository
extends JpaRepository<EntityClassName, DatatypeOfPrimaryKey>, EntityGraphJpaSpecificationExecutor<EntityClassName> {
}
userRepository.findAll(specification, pageable, new NamedEntityGraph(EntityGraphType.FETCH, "graphName"))

How to map a Spring Data JPA repository entity into a view model?

Here is the situation, I want to fetch an entity from database and map it to a new view domain model which has more or less properties, if this view model has more properties, signs the extra properties with default value. I want a map technique in JPA to complete this, which is similar to MyBatis mapping mechanism.
So how to do it?
Just load the entity, copy it over in the new entity, fill the unset properties with the desired default values and store it using JPA (possibly via Spring Data JPA).
For copying over the data from one entity to another you might want to look int Dozer or similar libraries.
You could also misuse Spring Data's projection support to query the original entity, but return it as the target entity with methods similar to the following:
interface SourceRepository<Source, Long> extends CrudRepository<Source, Long> {
List<Target> findTargetBy();
}
The resulting Target entities then could be stored again using another repository (you might have to set version and id properties to null to make it clear to the framework that these are new entities.

Combine DAO and Entity in Spring and Hibernate

I was wondering if it is possible to combine DAO and Entity in a single class. e.g.
In rails
If I have table named user then there will be one ActiveRecord User and by using that class I can access access Methods related to DB and user i.e. it has both methods user.name (accessing object properties) and user.save / User.get_all methods (managing DB interactions) in the same class
In Spring/Hibernate Configuration
I have two things: DAO and Entity
Entity: I have User class that is an entity and is mapping Table as POJO, so that I can access methods related to a single user e.g. user.getName()
DAO: I have a DAO in which there are DB interactions e.g. userDAO.save(user) and userDAO.get(id).
Question:
I was wondering if I can create single User class and define User properties and getter/setter inside along with DB interactions so that I can single class as both, i.e. user.getName() (as POJO) and User.get(id)/user.save() (as DAO).
Is this method possible, and why are the complications I might run into, if I start with this approach?
it's called Active Record Pattern . Here is article about topic for JPA . Active Record Pattern . and example https://github.com/ActiveJpa/activejpa
Is this method possible, and why are the complications I might run into, if I start with this approach?
it's :
Cohesion & Coupling
if it's real project , it might become problem to support it
when you have 20 entities it's difficult to decide where to put method into what entity , and also find method that you need as it might be in many places
when you don't use active record pattern you can share entity with web layer , with active record entity can't be Serializable.
code become bigger and bigger

Pentaho reporting connectionFactory has new method added but no description

I am in process of upgrading my pentaho reporting from 3.6.1 to 3.8.0 in my web application. when I updated all necessary jar files, I got one compilation error in one of my class which implements ConnectionProvider. following is my class.
public class DataSourceConnectionProvider implements ConnectionProvider
{
....
}
The error is saying that my class should implement getConnectionHash() method as it is defined in ConnectionProvider interface. but It was not there in 3.6.1 version. so I am bit confused why they have added it and how to implement it in my class.
This method returns a object that is comparable and hashable and is used during the caching of datasources. It allows us to build some sort of key to detect changes in the connection definition while many reports run within the same JVM.
The cache implementation itself does not know any of the details of the various datasources and the "ConnectionHash" allows us keep result-sets separate.
My basic implementation of it simply returns a ArrayList with all relevant connection properties added to it.
Simple example how and where it is needed:
Imagine you have a JDBC datasource that connects to a database where several schemas with the same table structures exists, for example in a multi-tenant environment where each tenant has his own schema.
With a query like "SELECT * FROM CUSTOMERS WHERE COUNTRY = ${country-parameter}" the datasource will return different datasets based on which tenant performs the query. The sum of "connection-hash", "query-name" and "parameter used in the query" now forms a unique identifier that we can use to store and later lookup the resultset from the cache.

Resources