Creating tables on fly with Spring Boot Data JPA - spring

Trying to build application where tables & its fields are managed by master table & creation of tables & its fields happens on demand, on fly based on user data posted to server.
Tried to look over similar question like this but wasnt able to find clue how to execute dynamic queries in DB without creating Repository & Entity in spring boot.

Robert Niestroj is correct when he writes in the comments
If you have dynamic tables JPA is the wrong approach. JPA is for static schema
I guess in theory you could do something where you generate code and possibly restart your ApplicationContext but it is bound to be really painful and you won't benefit from using JPA.
You should look into more dynamic technologies. MyBatis and plain old JdbcTemplate or NamedParameterJdbcTemplate come to my mind.
Possibly with your own abstraction layer on top of it if you have recurring scenarios.

Related

Multiple databases (Postgresql in RDS) but same spring repository and entity

I have a use case where I need to create exact same postgresql database in two different regions. Everything is same in these two databases i.e same schema and same tables and same data.
I have a use to achieve distributed transaction. So if a request land in region-a and write to region-a database to let's say Person table, then exact same record must be either written in Person table in both these database or if there is any error, write attempt should be rolled back.
I am trying to figure out if I can attach two different datasources with same Person Entity and CRUD repository in spring so the respoistory.save() method can write to Person table in both the databases.
So far, I have come across AbstractRoutingDataSource but that is for achieving multi tenancy in the databases. Other solutions are found are slightly different where use case is to write different records in different database (mostly sharding based on various data points).
Does spring provide any out of the box solution so I can achieve transactional write to same table in two different databases.
Does spring provide any out of the box solution so I can achieve transactional write to same table in two different databases.
Depends on your definition of "out of the box" - it doesn't itself implement distributed transactions, but does have support for using libraries that do. It is however relatively complicated to get everything working correctly, and requires additional components to be carefully configured in your runtime environment.
Spring Boot 2.x documentation on distributed transactions is here: https://docs.spring.io/spring-boot/docs/2.7.x/reference/htmlsingle/#io.jta
The Spring Boot 3.x documentation is here: https://docs.spring.io/spring-boot/docs/current/reference/html/io.html#io.jta but it's also worth noting that for 3.x, the Spring Boot team have changed direction and decided that integrated support should be provided by the relevant JTA provider (cf. https://github.com/spring-projects/spring-boot/issues/28589 ), and so there's projects like https://github.com/snowdrop/narayana-spring-boot

Only simple models in Spring Data JDBC

Im not sure if i can use Spring Data JDBC also for complex models. My doubts arise especially cause in the Spring Data JDBC (3.0) documentation is written:
"There is a simple model of how to map entities to tables. It probably only works for rather simple cases. If you do not like that, you should code your own strategy. Spring Data JDBC offers only very limited support for customizing the strategy with annotations." https://docs.spring.io/spring-data/jdbc/docs/3.0.0/reference/html/#jdbc.why
I was expecting Spring Data JDBC is also working for more complex cases.
The limitations that rise from this simple model affect mostly legacy projects where you have a database that you maybe can't even change.
Spring Data JDBC is not intended to map an arbitrary database model to an arbitrary Java domain model, but to use a Domain Driven Design approach and construct the database accordingly.
But even in the cases where you hit the limitations of Spring Data JDBC you can always fall back on Springs JdbcTemplate without any conflict with the rest of your model which gets persisted by Spring Data JDBC.
The same is not true for JPA. Of course you can use JdbcTemplate with JPA as well, but you now have to very different approaches to persistence in your application which can and will interact in interesting ways due to JPA caching and dirty checking.
I therefore think Spring Data JDBC is an excellent choice for large application and complex models.
It's limitations will push you in the direction of better defined smaller modules and less complex models.

Spring data JPARepository findById() on an Entity with #Version persists the record when no data is present for the primary key

Am using Spring Data JPA and hibernate in as springboot project for persistence, Whenever the method findyById() method on the Repository(JPA CRUD Repository) returns no data for the Primary key for an entity which uses #Version annotation for optimistic locking, it tries to insert an entity to the database.
I could see the insert query generated in the log file.
Has anyone come across such an issue? Please help.
The things I noticed from your explanation seem very strange to the program because this should not happen, you are just doing a simple query, it should not depend on the output of the query. Consider how much you have to look at different situations in very large application to avoid unexpected behaviors that cause problems.
One of the goals of ORM (Hibernate, etc.) is to ensure that the application meets your needs without worries.
There may be configuration on the side of your existing application that cause this problem.
In my opinion, to understand the problem, create another simple project with the minimum requirements, try again.

Is it a must to use spring-data-jdbc when using JdbcTemplate?

I am planning to use Spring JdbcTemplate to access my database. Is it a must to use spring-data-jdbc when using JdbcTemplate? The reason I am asking is I don't need "entity"(POJO) for my table in my application. Would it add some overheads if I use spring-data-jdbc?
You can use the JdbcTemplate without Spring Data JDBC without a problem.
JdbcTemplate existed for many years before Spring Data JDBC was conceived.
Spring Data JDBC does involve an overhead.
It extracts data from POJOs, creates queries and transforms the result back to POJOs.
Of course all that takes resources.
If you don't need/benefit from it don't use it.
You can also start with JdbcTemplate and later start using Spring Data JDBC without a problem if the need arises.
JdbcTemplate is part of the spring-jdbc module, so you only need that (and sprint-tx, which includes the DataAccessException hierarchy).
spring-data-jdbc adds support for (not surprisingly) spring-data on top of spring-jdbc. So you don't need it to use JdbcTemplate, the same as you don't need spring-data-jpa to use the JPA EntityManager.
Spring-data-jdbc is implemented on the basis of spring-jdbc. If you don't need Entity at all, then using spring-jdbc to interact directly with the database is the most convenient and flexible. In this case, using spring-data-jdbc is just a pure increase in learning costs. Spring-data-jdbc is designed for DDD (Domain Driven Design) mode, which is different from the current mainstream programming model. The learning cost is not low...

What's the difference between Spring Data MongoDB and Hibernate OGM for MongoDB?

I have not used Spring Data before but I've used Hibernate ORM a number of times for MySQL based application. I just don't understand which framework to choose between the two for a MongoDB based application.
I've tried searching for the answer but I can't find the answer which does a comparison between the two in a production environment. Has anyone found problems working with these two frameworks with MongoDB ?
Disclaimer: I am the lead of the Spring Data project, so I'll mostly cover the Spring Data side of things here:
I think the core distinction between the two projects is that the Hibernate OGM team chose to center their efforts around the JPA while the Spring Data team explicitly did not. The reasons are as follows:
JPA is an inherently relational API. The first two sentences of the spec state, that it's an API for object-relational mapping. This is also embodied in core themes of the API: it talks about tables, columns, joins, transactions. Concepts that are not necessarily transferable into the NoSQL world.
You usually choose a NoSQL store because of its special traits (e.g. geospatial queries on MongoDB, being able to execute graph traversals for Neo4j). None of them are (and will be) available in JPA, hence you'll need to provide proprietary extensions anyway.
Even worse, JPA features concepts that will simply guide users into wrong directions if they assume them to work on a NoSQL store like they were defined in JPA: how should a transaction rollback be implemented reasonably on top of a MongoDB?
So with Spring Data, we chose to rather provide a consistent programming model for the supported stores but not try to force everything into a single over-abstracting API: you get the well-known template implementations, you get the repository abstraction, which works identical for all stores but lets you leverage store-specific features and concepts.
Disclaimer: I'm one of the Hibernate OGM developers so I'll try to provide some of the reasons behind it.
Hibernate OGM provides Java Persistence (JPA) support for NoSQL solutions. It reuses Hibernate ORM’s engine but persists entities into a NoSQL datastore instead of a relational database. It also aims to provide access to specific datastore features when JPA does not have a good fit.
This approach is interesting for several reasons:
Known semantic and APIs. Java developers are already familiar with JPA, this means that one won't have to learn lower level API. It also supports both HQL and native backend-queries.
Late backend choice. Choosing the right NoSQL datastore is not trivial. With Hibernate OGM you won't have to commit to a specific NoSQL solution and you will be able to switch and tests different backends easily.
Existing tools and libraries. JPA and Hibernate ORM have been around for a while and you will be able to reuse libraries and tools that uses them underneath.
Most of JPA logical model fits. An example of a good fit is #Embedded, #EmbeddedCollection and #Entity (that can be a node, document or cache based on the datastore of choice). Admittedly, annotation names might be strange because you will also have to deal with #Table and #Column.
JPA abstracts persistence at the object level, leaving room for a lot of tricks and optimizations. We have several ideas planned, like polyglot persistence: storing data in several data stores and use the best one for a specific read job.
The main drawback is that some of the concepts of JPA are not easily mapped to the NoSQL world: transactions for example. While you will have access to transaction demarcation methods, you won't be able to rollback on data stores that don't support transactions natively (transactions, in this case, will be used to group operations and try to optimize the number of calls to the db).
Also, if your dataset is by nature non domain model centric, then Hibernate OGM is not for you.
One can Just go with SpringData. If you recall Spring ORM also uses some JPA things such as Entity, Transaction and provided best commination of things from JPA and Hibernate APIs a. Spring community will take care in future versions if JPA is getting more matured for NoSQL.
Though it is not the main reason. Most of reasons are described by #Oliver Drotbohm.
Read more documentation of SprinData and further analyse your data model, scalability on continuity/growth of data store, find best fit for your solution and consider suggestion given by #Davide.
Many cases SpringData has got more success rate than JPA while integrating with MongoDB.

Resources