I want to define a jndi object as simple string for each of my servers with in a server group;
I can define a jndi object as a simple string for a profile, and a profile can be attainable to a server-group, so when I define it in this way, all of my servers in this server group would see the same value, however I want to make the value to be different for each of my servers.
Related
I am creating a Springboot application with OpenJPA.
My requirement is that I need to connect to multiple datasources dynamically and the datasource credentials are obtained at runtime by calling some rest-endpoints.
Here is the controller class:
#RestController
public class StationController {
#Autowired
BasicDataSource dataSource;
I have a service which returns me the jdbc_url depending on the customer name:
public String getDSInfo(String customername){
// code to get the datasource info (JDBC URL)
}
My questions are:
Is there a way in which I can create datasources at runtime by getting datasource credentials by calling some other service (which takes the customer id and returns the customer specific datasource) ?
Since my application is a web based application, many customers will be accessing it at the same time, so how to create and handle so many different datasources?
NOTE:
The code will get information about the customer specific data source only by firing some service at the runtime, so I cannot hardcode the datasource credentials in the XML configuration file.
I found some implementations with Hibernate but i am using Springboot with OpenJPA. So need OpenJPA specific help.
It sounds like you want a multi-tenancy solution.
Datasources are easy to create programmatically, just use a DataSourceBuilder with your connection details pulled in from a central source (e.g. a central config database or Spring Config Server).
Then you'll need to look at a multi-tenancy framework to tie the datasources back to clients.
See here:
https://www.youtube.com/watch?v=nBSHiUTHjWA
and here
https://dzone.com/articles/multi-tenancy-using-jpa-spring-and-hibernate-part
The video is a long watch but a good one. Basically you have a map of customer data sources (from memory) that allow an entityManager to pick up a datasource from the map by using a thread scoped custom spring scope of "customer" which is set when a user for a particular customer somehow logs into your app.
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)
I am building a web application that makes use of Entity Framework. I have moved the Entity Model and generated classes to a separate project, because it will be used by more than one consumer.
But when I try to run the application, Entity Framework tells me that
No connection string named 'X' could be ofund in the application config file.
To remove this problem, I would have to add the Entity Framework connection string to every consuming project. Of course this is annoying, because there are several consumers, and also it introduces a tight coupling that i hoped to get rid by dividing the software into different projects.
So is it possible to define the connection string in only one place and not in every consuming project?
NOTE: I am following the Database First approach.
This is possible, because you can instantiate a context with a constructor that accepts a connection string. In one of our projects we have a ContextFactory where the connection string is registered once at startup. All code in the assembly gets contexts from the factory.
Actually, in our case we use an ObjectContext, and create the connection string for the factory from the connection that is registered and the metadata string that was created when creating the context. We do this by using an EntityConnectionStringBuilder.
1. Question
What are known strategyies, solutions for LAZY-loading from client side?
I was checking out this stuff http://wiki.eclipse.org/Introduction_to_EclipseLink_Sessions_(ELUG)#Remote_Sessions but not sure if this is a solution to my problem or how to use this.
2. Use-case
I'm developing a three tier application where my presentation layer (Eclipse RCP) is a remote client over network:
[ Eclipse RCP ] <-----(RMI)-----> [ [EJB 3] [JPA 2] [Mysql] ]
Now, I use JPA Entities as my domain model which I want to use in my client as well. I get the entites from #Session beans over network.
Problem happens when my JPA Entites have LAZY fields. After serialization and especially because my JPA provider (EclipseLink) is over the other side of the network I need a strategy to load those LAZY fields from client.
I'm going to have many entities: 30-40 maybe. And typical scenario would be when the user sees a list of SomethingModel which has many List fields, but those are not needed to be shown on the list, only when she want's to change a specific element.
3. Possible Solution
I came up with one solution e.g.: I create proxy classes for my JPA entites in client side. When I need a collection field from my Domain model, the proxy class will call the remote EJB to populate the field.
class CarModelClient {
CarModel model;
public String getColor(){
model.getColor();
}
public List<Wheels> getWheels(){
CarModelFacadeRemote carFacade = //get my remote ejb
model.setWheels( carFacade.getWheels( model.getId() ) );
return model.getWheels();
}
}
Well, similar to that.
Thank you for your answers.
Don't try to be too smart and pretend like the client was on the server, and the entity manager was always open. Consider the domain objects, at client-side, exactly as you would consider DTOs or JSON objects: objects containing some information coming from the server and seralized over the wire.
Document the service methods called from the client (the facade methods) to specify which associations are initialized and which are not in the returned entities. If you are on some "list" screen and want to see the detailed view of one of the elements of the list, for example, call another service which loads the entity again from the database (and thus gets fresh results), with probably other associations initialized in order to display more details about the entity.
Trying to dynamically initialize the lazy-loaded associations at the client just doesn't work: it's complex, inefficient, results in an obsolete and incoherent graph on the client, doesn't take transactional isolation into account.
I am trying to deploy my JPA application on 2 separate instances within the same glassfish 3 domain. Both instances will be looking up a datasource using the same JNDI name, but I want them to find different datasources.
I tried to define 2 datasources and bind them to different targets, but the DAS does not allow 2 datasources using the same JNDI name even though they are bound to different targets.
I tried to use property substitution but that didn't work. Does anyone know how to solve this? It seems unlikely that there's no way to deploy an application twice in the same domain.
A JNDI name is an address for a specific object, and they must be unique. Having two JNDI names is like when you have 2 numbers in your cellphone for "alex". There is no way to know which are you dialing.
What I would do, which should work for any JPA implementation, is to have two PUs on your persistent.xml, one with a JNDI datasource and another for the other JNDI datasource. This also makes sense because you might not have the same business objects on both datasources.
Then, when you get you EntityManager, specify explicitly which PU you want. You might set this in a configuration file or decide it dynamically some other way.
entfactory = OpenJPAPersistence.createEntityManagerFactory( *persistentUnitName*, (String) null );
Hope this helps --
-Alex