I am using eclipseLink JPA and i am using same db for two different EJB applications deployed in two different servers. I am getting concurrency issues due to JPA cache if other application is doing some modification on the same object. Is there any way i can manage this concurrency issues. Using native query for db operations is not an option. I am using oracle db and glassfish server. is there any solution available for this.
Let me explain why you have issues:
Imagine you have cached data for object. So the first application will work with that cached data and there are no need to this application to go to database (as it already have the value in memory). It can upgrade that cached data if you will perform another modifying query on the same entityManager. It in no way can know that the other application changed state of your data.
So isolation level won't help as there will be no read query from first application as it already have cached value. And as far as entityManager know is only the operations from that same manager. It have no way to know about another entityManager on different application.
The solution is to not to cache. Or you can configure external cache as your second level cache which you can evict from both applications (like hazelcast cache for example).
Related
We have a DB2 database which is used by legacy applications that we are in the process of decommissioning and we have an Oracle database that we are developing new applications for. In order to maintain compatibility with legacy applications until they are completely decommissioned and keep data in sync, we are using Atomikos for two phase commits. This however is resulting in a lot of duplicated entities and repositories and thus technical debt, because the same entities and repositories cannot be used by the same entity managers so we have to duplicate them and put them under different packages for the entity scanning.
In most cases we want to read data from the legacy database and persist to both, but ideally this would be configurable.
Any help on this would be greatly appreciated.
In documentation it says "JPA doesn't have a concept similar to the Hibernate StatelessSession so we have to use other features provided by the JPA specification." - what does this mean? Hibernate is one of the jpa impl so bit confused here
Looking for example where we use jpa infra that we have (entity/crud repo) and we want to use that to read data and write data. Most examples talk about file reading and writing and some about jdbc cursor reader. But since we are using other feature of hibernate like envers we want to use same jpa way that we are using for our online transactions. We are using spring boot/jpa (hibernate) out of the box with oracle and in memory h2 db for dev.
In prod we use oracle, we have user that access to some schemas, how we can inform spring batch to use particular schema to create tables. Right now for some time same application will be use for batch and online so we dont want to use second datasource and different user for batch if possible. Isnt this very basic requirement for all?
Good documentation of spring batch and also liked java/xml config toggle.
We use springboot 2.x with batch.
In documentation it says "JPA doesn't have a concept similar to the Hibernate StatelessSession so we have to use other features provided by the JPA specification." - what does this mean?
The direct equivalent of the Hibernate Session API in JPA is the EntityManager. So this simply means there is no API like StatelessEntityManager in JPA, and we need to find a way to achieve the same functionality with JPA APIs only, which is explained in the same section: After each page is read, the entities become detached and the persistence context is cleared, to allow the entities to be garbage collected once the page is processed.
we want to use same jpa way that we are using for our online transactions.
You can use the same DAOs or repositories for both your web app and batch app. For example, the ItemWriterAdapter lets you adapt your hibernate/JPA DAO/repository to the item writer interface and use it to persist entities.
In prod we use oracle, we have user that access to some schemas, how we can inform spring batch to use particular schema to create tables. Right now for some time same application will be use for batch and online so we dont want to use second datasource and different user for batch if possible. Isnt this very basic requirement for all?
You can use the same data source for both your web app and batch app. Then it is up to you to choose the schema for Spring Batch tables. I would recommend using the same schema so that data and meta-data are always in sync (when a Spring Batch transaction fails for example).
Hope this helps.
I have an application I'm building in Play! Framework with a bunch of data that I would like to track changes to. In a enterprise solution, I would likely use database triggers to copy the changes to a historical table to track those changes. I am not familiar with a similar paradigm in Play!/JPA, but maybe I'm missing something. Is there a decent way to do this other than me creating a copy of all of my entities and manually copying the data from the old/unchanged record to the historical, then saving the changes to the original model?
If you data is very critical to keep all the data changes I would stick with the triggers. Because as database doing the updates so there is no possible clock skew in the cluster running the web app and if a non-JPA client accesses the database then you could keep updates as well.
However, if you are not so obsesive about these kind of concerns than I would suggest you magic EntityListeners such as:
#PrePersist
#PreUpdate
#PreRemove
#PostPersist
#PostUpdate
#PostRemove
Here you could find examples of how to use EntityListener,
If you use EclipseLink JPA, you can enable history support.
See,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/History
It is possible to use EF with only an in memory DB that is not persisted in anyway kinda like what DataSet does. The information in the DB would only be required while the app is running and would not need to be retained. I have searched and studied but can’t find the answer.
You can use SQLite(http://www.sqlite.org/inmemorydb.html) in-memory database with entity framework. See these threads. http://sqlite.phxsoftware.com/forums/t/2604.aspx , Integration Testing Entity Framework code first with in-memory database
I work on an existing Seam 2.2.0 + JPA (Hibernate 3.3.1) application that needs to be converted to a 'single database per client' environment where each database schema is the same. The application runs on Glassfish, uses IceFaces, and has several pages that utilize Conversations. It also uses a single EJB for authentication. Unfortunately, the decision to split clients off into their own databases is outside of my control.
As a proof of concept, I have already made the application aware of multiple databases by moving the management of EntityManagerFactory(ies) and DataSource(s) into the application using Spring JPA abstractions, resource local transactions, and ThreadLocal for context information. For example, each time a user logs in a new EntityManagerFactory is initialized using a new DataSource that communicates with their database if it has not already been initialized. This is working well in a test environment with a handful of databases.
My question is, will this approach scale to hundreds of databases? I expect to add application servers to a load balancer to handle additional load, but will the overhead of the Hibernate/JPA first-level cache and/or Seam context management (a.k.a., memory consumption) require significantly more servers to scale compared to a typical load balanced application? If so, can this be mitigated by allocating servers with lots of RAM and/or a large distributed cache?
Any insight would be greatly appreciated.
I worked on an application with this approach and I what I can point out is:
Datasource and EntityManagerFactory management is the hard part. However it seems you did this already in the test environment. Double check if you did things right in respect of the Seam Managed Entity Manager.
Your application won't scale well on hundreds of databases because you have a linear increase of memory consumption for each database. In fact, for each database you are going to have different instances of EntityManagerFactory (Hibernate SessionFactory) each requiring a considerable amount of Ram.
Beware of possible issues if you configure Hibernate second level cache. Since all SessionFactories are created from the same data model the cache region names may collide. I used hibernate.cache.region_prefix configuration parameter to make these names uniques among the various instances using the database id as the cache prefix.