Dynamicly select datasource for entities runtime - jpa

I have an entity bean that will represent an expected result over multiple databases/datasources and can also be different queries executed, but same result always comming back. So the bean is re-used over different datasources that should be able to be dynamicly selected.
Is it possible with JPA to select during runtime the data source to be used to execute a query, and return the same type of entity bean?
Also, does my ejb/application need to define the datasources that will be used? Or can I always specify via jndi what datasource to use? Modifying the descriptor's and re-deploying an application everytime a new datasource is created is not an option.
Sorry if the question does not make 100% sense, rather difficult to get the idea through.

Is it possible with JPA to select during runtime the data source to be used to execute a query, and return the same type of entity bean?
You can't change the datasource of a persistence unit at runtime. However, you can configure several persistence unit and use one or another EntityManagerFactory. Maybe JPA is not the right tool for your use case.
Modifying the descriptor's and re-deploying an application everytime a new datasource is created is not an option.
And how will the application be aware of the "available datasources"?

You can change the JPA datasource at runtime, but the approach is tricky (introspection, JPA implementation specific, ...).
I've implemented my own implementation of javax.persistence.spi.PersistenceProviderwhich override the org.hibernate.ejb.HibernatePersistence and sets the datasource in both the Map and PersistenceUnitInfo of the PersistenceProvider just before creating the EntityManagerFactory. This way, my EntityManagerFactory has a datasource which has been configured at runtime. I keep my EntityManagerFactory until the application is undeployed.
You could use the same be approach and create N different EntityManagerFactory, each with its specific datasource. However keep in mind that each ÈntityManagerFactory uses a lot of memory.

Related

Javers and MyBatis integration help needed

I'm having issues trying to get MyBatis and Javers (with Spring) integrated and working. I've followed instructions at http://javers.org/documentation/spring-integration/ and gotten the Aspect setup, and annotated my entity class and registered it with Javers, and the MyBatis interface correctly annotated with #Repository and #JaversAuditable on the appropriate methods, but still haven't gotten it to work, even setting breakpoints in the Javers Aspect, but nothing triggers.
I've also gone about it the other way, using MyBatis plugin interceptor, as per http://www.mybatis.org/mybatis-3/configuration.html#plugins (then used http://www.mybatis.org/spring/xref-test/org/mybatis/spring/ExecutorInterceptor.html as a basic example for commits). However while it's triggering, it's not doing what I expected and is basically just an aspect around on the commit method, which takes a boolean rather than containing which entity(ies) are being commited which would let me pass them to Javers. I suppose I could add an interceptor on the update/insert MyBatis methods, and then stored that in a ThreadLocal or similar so that when commit/rollback was called I could pass it to Javers as necessary, but that's messy.
I've got no clue where to go from here, unless someone can see something I've missed with one of those 2 methods.
So in my confusion, I realized that since MyBatis generates the concrete object for the Mapper Interfaces, Spring never seems the creation of that object, simply has the final object registered as a Bean in the context. Thus, Javers never has a chance to process the Bean as it's created in order to do any proxying or what not as necessary.
So, silly me. So I ended up creating a Spring-Data #Repository layer that mostly just passes the call through to the Mapper. Although on updates I'm doing some extra bits which the DAO shim layer (as I'm calling it) works well for.

Java EE Wildfly retrieve EntityManager from JNDI without persistence.xml

I have recently moved to Java EE (Wildfly) and I'd like to lookup an EntityManager from JNDI. At present I am defining a datasource in my standalone.xml and successfully retrieving this via JNDI but this provides me with only the Datasource and not an Entity Manager.
I am aware that I can create a persistence.xml and use #PersistenceContext but I am really looking at a way to avoid compile time knowledge of the JNDI name, so instead want to perform a lookup based on runtime information to retrieve the appropriate Entity Manager.
Unfortunately a persistence unit, from which an entity manager is derived can not be defined in a portable way without using a persistence.xml file.
If this is important for you please consider voting for JPA_SPEC-114 and additionally providing a comment there.
You can, more or less, make the persistence unit independent of the final JNDI name by using a resource-ref. A resource-ref does causes your code to become dependent on a container specific mechanism to switch what the resource-ref is pointing to.
An alternative, with its own cons unfortunately, is using a switchable data source approach. You can then define a data source using a fixed JNDI name and reference that from a persistence.xml file, and then use whatever method your switchable data source uses internally to go to the actual data source. This can then be either directly a data source implementation (such as shown in the link) or perhaps fetching another data source from JNDI (which effectively does what resource-ref does, but then using your own mechanism to switch)

Why are my entities only partially populated when loading them using Spring Data JPA?

I'm using Spring Data JPA and DataNucleus as JPA persistence provider and have something like
interface BookRepository extends CrudRepository<Book, Long> {
Book findByAuthorId(Long id);
}
If I call bookRepository.findByAuthorId() and then access book.publishingHouse.manager.name is null. As opposed to calling bookRepository.findAll() when the fields are populated correctly all the way. I set datanucleus.DetachAllOnCommit=true and datanucleus.maxFetchDepth=-1 (I also tried with 10).
Any idea why?
If you don't have any additional transaction boundaries defined, the EntityManager closed when leaving the query method. That means what you get back is detached entities and what kind of load state you get back is determined by the defaults the persistence provider uses.
You basically have two options:
Have a client (service or controller class) using #Transactional to keep the EntityManager open and thus the loaded instances eligible to lazy-loading to pull data out of the store while you use the instance. If a controller or service is not enough, you might wanna look into the OpenEntityManagerInViewFilter/-Interceptor which basically keeps the EntityManager open until the view is rendered.
Define what should be fetched explicitly either using JPA 2.1 entity graphs (see the reference docs for details) or explicitly adding fetch-joins to the query by defining it manually.

In a system using EJB 3.1 and JPA 2.0, where should one cache CriteriaQuery objects?

The JPA 2.0 specification mentions in section 6.9 that CriteriaQuery objects are serializable, and hence may outlive any open EntityManagers or EntityManagerFactory instances:
CriteriaQuery objects must be serializable. A persistence vendor is required to support the subse- quent deserialization of a CriteriaQuery object into a separate JVM instance of that vendor’s runt- ime, where both runtime instances have access to any required vendor implementation classes.
The EJB 3.1 specification says in section 21.2.2:
An enterprise bean must not use thread synchronization primitives to synchronize execution of multiple instances, except if it is a Singleton session bean with bean-managed concurrency.
If I have a stateless session bean that wishes to pre-build a bunch of CriteriaQuery objects using a CriteriaBuilder obtained from an injected #PersistenceContext, where should I stash the results?
I can think of the following possibilities but am concerned that all but one run afoul of the "no synchronization primitives" clause above:
In a Map that is stored as the value of one of my bean's instance fields, understanding that I'll have to synchronize access to the map. My take: section 21.2.2 violation.
In a ConcurrentMap that is stored as the value of one of my bean's instance fields. My take: still a section 21.2.2 violation, as I'm sure the ConcurrentMap implementation synchronizes somewhere.
In a #Singleton EJB's instance field somewhere, where the #Singleton exists only to serve as this kind of cache; with bean-managed concurrency this should be legal, but now all my stateless session beans that want to make use of this CriteriaQuery cache have to inject the singleton into themselves...seems like a lot of overhead.
So it sounds like strictly speaking the last option is the only specification-compliant one. Am I correct?
I would consider putting them in a simple static context, accessible from anywhere. The problem lies in initializing them since you need an entity manager instance to do that. Perhaps a singleton ejb for initializing things as described at Call method in EJB on JBoss startup. The singleton could initialize your criteria query cache, which then could serve criteria queries to your DAOs through static context.
Another option would be to use JPQL which has built in support for precompiled queries. Of course you'd lose some advantages of using the criteria API, though I think the main issue (type safety etc.) might be OK since precompiled queries should throw an exception if they are invalid at deploy time rather than runtime.

compare two EntityManagerFactories for having PersistenceUnits with identical connection attributes

Having two JPA2 (EclipseLink) EntityManagerFactory instances what would be the best way to detect that their PersistenceUnit attributes are identical?
You can call getProperties() to get the persistence unit properties and compare them.
Normally EclipseLink will use the same EclipseLink ServerSession if the same persistence unit is used twice. You can call unwrap(Session.class) to get the session, and see if they are the same.
I think you're best hit would be to get (somehow, someway, ...) access to the PersistenceUnitInfo interface which is implemented and created by the container and passed to the JPA provider. The JPA provider uses it when creating the EntityManagerFactory.