I'm designing an application that will use data from several databases. I'll use JPA to implement persistence and Spring as main application framework.
I need to handle transactions that will span among different datasources. Googlin' a bit I found that JtaTransactionManager could be useful to implement this.
But I'd also like to create relations (at application level) among entities belonging to different datasources. So that I can work as if the data-layer consists of a single database, without having to worry about the source which the entities "come from".
Will JtaTransactionManager let me do this, or I need some extra component or configuration in Spring?
I know no easy existent solution to your problem.
The JtaTransactionManager will take care of executing operations with different databases/datasources within the same transaction, but you won't have the data consistency guaranteed by any databases (like foreign keys between databases).
Besides, JPA does not support #ManyTo* relationships between different databases (like EntityFromDb1 has a OneToOne relationship tp EntityFromDb2), so the solution would be to work with the corresponding Ids. Afterwards it is your task to manage those relationships. Of course with some work from your behalf you could automatize the load of relationships, but there is much more that only that, like cascading, locking, queries joining both databases...
Related
I'm Using Seedstack 16.7 and its Business framework with JPA plugin support.
There's 2 ways to acquire data from a datasource.
Repositories http://seedstack.org/docs/business/manual/repositories/
They are pretty much the ones that acts in behalf of an traditional EntityManager on JPA, keeping the type safety.
Finders http://seedstack.org/docs/business/manual/finders/
They retrieve Dto from a datasource.
The only apparent difference between them is that finder is a read only interface to a datasource.
Most of the queries that a finder requires can be done just by calling a repository and converting from a Aggregate to a Dto
Is there any real difference between them, or on their intended?
other than stated on this question.
It is somewhat complex to explain it in a few lines because that modeling decission comes from deep understanding of DDD, CQ(R)S, fast readmodels, eventual consistency, etc.
Finders
As the manual says: "Query the persistence layer or any data source to obtain objects specific to an interface of the application".
The keyword here is Interface. In the case of a graphical UI the use of finders is to retrieve a concrete view to present it in a desktop form or webpage. In a non CRUD app the UI should be Task-Based so:
Your views does not match your Entities and Aggregates.
Your Entities and Aggregates does not (should not) contain the full lists of selection data i.e.: States and Cities (classic cascading dependency comboboxes)
Your Aggregates and Entities does not (should not) contain the full list of referenced Entities (A Customer class with a hurge list of Orders, with all order data, placed inside is wrong DDD aggregate modeling) but somewhere in your app you have to show full order list.
Your Views and Aggregates can be retrieved from different data sources (usually for query performance and/or eventural consistency). i.e NoSql readmodels, a non normalized relational database or precomputed views (instead of tables representing your Entities) in your domain relational database.
So you have a impedance mischatch betwen UI and Aggregates/Entities. The best way to resolve this is create, explicitly, a way to deal from persistence to view. Finders comes into play.
Repoisitories
When a user issue a command that implies a change in your domain you have to retrieve an aggegate and use the aggregate root as entry point of the action. This ensures consistency and invariants (rules) of your domain. Aggregate modeling has a lot of nuances (take a look here) that makes bad idea to try using aggregates and entities for your views. So you need a way to read and build in memory aggregates from data sources. This is the job of repositories. Sometimes repositories gives you extra features that you do not need when retrieve data for views like entity change tracking, creation of unique identifications to persist, etc. You do not need anything of this when dealing with views. Repositories comes to play.
Should JPA Entities match the constraints of the database they're mapping?
What about database triggers used for data generation, should those be match as well?
Yes, you should model the constraints in your JPA model, as it is best to state those constraint explicit in your entities.
On one side because just of documentation purposes (many developers will look into your entity model while nearly none of them will look into the database model when using your beans).
On the other because you can catch wrong input as early as possible (potentially even in your UI), because many frameworks like JSF will look at them.
And you should try to move triggers from your database to your entities - to keep the application logic in one place and make such things explicit. But it makes no sense to double that logic - so if you need to keep these triggers in the database, don't add the same in the entities (but you should mention the triggers in the JavaDoc then).
Is it possible to create relationships (#OneToMany , #ManyToMany) between two entities in two different persistence units?
After following this set up http://viralpatel.net/blogs/spring-roo-two-database-configuration/
i want to see if an entity created with one persistent unit context can interact with another entity on another context.
If this isn't possible, do i just have to manage transactions on my own?
You cant have relationships across two different contexts/databases.
Some databases allow you to setup db-links. These create a virtual schema/db in the database which looks likes in the same db even though it is not. However, I have found these types of solutions to be slow and problematic.
Also, when dealing with 2 different db's, transaction management becomes more complicated. You can use the full 2 phase commit transaction management. Or you can use a custom transaction manager that works specifically on your 2 database instances.
In our project we have a constraint of not having the luxury to alter the table structure already in place. The tables are highly denormalized in nature.
We have come up with good POJOs for the application. We have the Entity beans generated out of the exiting tables. Now we have to map the POJOs to the entities so that we can persist.
Ultimately, we combine a good POJO with a bad table. Any thoughts on options/alternatives/suggestions to this approach?
Hibernate/JPA(2) has a rich set of functionality to manipulate the mapping (so that your objects can differ from the tables), so that many (NOT ALL) old tables can be mapped to normal object. -- May you should have a look at this first, any use your pojo/table-"solution" only if this mapping is not powerful enough.
If you have a read only application, you can think of using views to make your table/views more like you objects. This may reduse the amount of strange mapping.
I don't know your mapping, size of the application or use case, but have you considered not to use Hibernate? I ask this, because I can imagine (how I said: I don't know you application), that in a architecture like this, no Hibernate feature is used and so Hibernate will add only a not needed complexity.
If you are using Hibernate you should be able to map your POJOs to the table structure using only XML files, without creating new Java beans. This would allow you to easily change the mapping if all of a sudden you can change the tables structures and make the economy of intermediary beans. That's the best you can do.
There's an enterprise application using Java + Hibernate + PostgreSQL. Hibernate is configured via annotations in the Java source code. So far the database schema is fixed, but I faced the problem that it needs to be dynamic:I can receive data from different locations and I have to store these in different tables. This means that I have to create tables run-time.
Fortunately, it seems that all of these data coming from the different institutes can have the same schema. But I still don't know how to do that using Hibernate. There are two main problems:
How to tell to Hibernate that many different tables have the same structure? For example the "Patient" class can be mapped to not just the "patient" table, but the "patient_mayo_clinic" table, "patient_northwestern" table, etc. I can feel that this causes ambiguity: how Hibernate knows which table to access when I do operations on the Patient class? It can be any (but only one) of the former listed tables.
How can I dynamically create tables with Hibernate and bind a class to them?
Response to suggestions:
Thanks for all of the suggestions. So far all of the answers discouraged the dynamic creation of tables. I'll mark Axel's answer, since it achieves certain goals, and it is a supported solution. More specifically it's called multi-tenancy. Sometimes it's important to know some important phrases which describes our problem (or part of our problem).
Here are some links about multi-tenancy:
Multi-tenancy in Hibernate
Hibernate Chapter 16. Multi-tenancy
Multi-tenancy Design
EclipseLink JPA multi-tenancy
In real world scenario multi-tenancy also involves the area of isolating the sets of data from each other (also in terms of access and authorization by different credentials) once they are shoved into one table.
You can't do this with Hibernate.
Why not extend your patient table with an institute column?
This way you'll be able to differentiate, without running into mapping issues.
I am afraid you can't do this easily in Hibernate. You would have to generate the Java source, compile it, add it to your classpath and load it dynamically with java.reflection package. If that works, which I doubt it, it will be an ugly solution (IMHO).
Have you consider using a schema less database i.e: NoSQL databases or RDF
databases. They are much more flexible in terms of what you can store in them , basically things are not tight up against a relational schema.
In most environments it is not a good idea to create tables dynamically simply because dbas will not give you the rights to create tables in production.
Axel's answer may be right for you. Also look into Inheritance Mapping for Hibernate.
I agree that its not advisable to create tables dynamically nevertheless it's doable.
Personally i would do as Axel Fontaine proposed but if dynamic tables is a must-have for you I would consider using Partitioning.
PostgreSQL allows you to create ona main table and few child tables (partitions), records are disjunctive between child tables, but every record from any child table is visible in parent table. This means that you can insert rows into any child table you want using just simple insert statement (its not cool but has the same level of complexity as composing and persisting an entity, so its acceptable in your case) and query database using HQL