How dynamically define properties for JPA connection with Injected EntityManager - java

How can I configure persistence.xml for production? My question specifically concerns the definition of parameters such as user, password and bank url, for example.
I would like to not include this data directly in the file, but in an environment variable, for example.
However, it can be any other approach, except overwriting the file settings via the entity manager factory as was said in these questions 1 e 2
This restriction exists because my EntityManager is injected via #PersistenceContext. This even generated a comment
I'm using a JavaEE application with JAX-RS, Hibernate JPA and Spring MVC

Related

Using an EJB outside container

I am currently creating a J2EE application and there is a part of it that is running outside the container, using a ServletContextListener to launch it.
However I also need to access the database from this part.
I currently have an Entity and a Stateless Session bean to fetch use the EntityManager.
I tested multiple things ( EntityManagerFactory, Initial Context, EJBContainer ) but I didn't manage to make any of them work.
How do I need to do it ?
You do not need EJB, actually you cannot create Ejbs outside the container. You need JPA, an OR-mapper and JDBC.
These normally are correctly configured in your EJB-Container. Outside the container you have to do that yourself.
You have to define your dependencies right, so that the correct JDBC-Driver is available and the OR-Mapper (probably eclipselink or hibernate?)
After that, you need define a presistence.xml to define the Entities to be used and to define how the DBMS is accessed via JDBC.
If that all is correctly configured EntityManagerFactory is the correct way to create an EntityManger for the persistence-unit defined in persistence.xml.
There are many examples available on the net. e.g.:
https://examples.javacodegeeks.com/enterprise-java/jpa/java-persistence-xml-example/
should work, if you are using eclipselink.
https://docs.jboss.org/hibernate/orm/3.6/quickstart/en-US/html/hibernate-gsg-tutorial-jpa.html
in case of Hibernate.

Change Java Spring Boot Bean while runtime

Hello fellow developers,
i created a library using the Spring boot framework.
This library is creating a dynamic database connection using #Beans where i create a "data" Bean which holds the unlimited Datasource beans provided by a Postgresql db. At the end i wanted to have a dynamic db connection which could be triggered from outside to change the db i want to connect to. The information of the different databases where stored as mentioned inside of a postgres. This is loaded at the application start into this bean. My Problem is, that i'm not able to switch between the different Datasource beans. Spring boot is creating them, but it seems like it's not possible to change the bean started at runtime of the application which only holds one of the unlimited Datasources... So also after a retriggering of the creation of the original bean it still uses the old datasource.
Is there a way to use the beans from spring boot and change them on runtime?
Regards,
Andreas
I believe you are asking for DB multitenancy support where tenants information is stored in a Postgres DB.
Configuring the persistent layer for multi-tenancy support involves configuring:
Hibernate, JPA and Datasources properties
Datasources beans
Entity manager factory bean
Transaction manager bean
Spring Data JPA and annotation-driven transactions
I recently blog about Multi-tenant applications using Spring Boot, JPA, Hibernate and Postgres and although the tenants data is stored in a yml "properties" file, it shouldn't be difficult to convert it to read tenant data from a DB. I think it would be a starting point for what you would like to accomplish.

Persistence context scope in a ejb j2ee and other questions

My apologies for lengthy question.
I'm working on a EJB application. I have two EJB eclipse projects(Ejb1 and Ejb2) and other dynamic web application(Web1) which will be compiled and added to a parent EjbEar project and packaged as EjbEar.ear file.
Question1: I've first created a persistence.xml in EJb1 project's META-INF folder and this helps me inject the entitymanager into the session beans and start working. (code below)
#PersistenceContext(unitName = "ejbPersistanceunit")
private EntityManager em;
In Ejb2 I've created another session bean and injected the entitymanager same like above(here I did not configure the persistence.xml) but when I invoke from the client, I get the response from both the Ejb1 and Ejb2 projects.
Why does the EntityManger get shared between two ejbprojects? If my Ejb2 project needs another persistence.xml for a different data source, do I create another one or have it included in the existing persistence.xml? will it also be shared ? Does my Web1 project also get hold of the Entitymanager in the same way?
Question2: I have sessionbeans in Ejb1 project and their remote interfaces are created in Web1 project but what is the best approach in exposing these newly created Entities/Interfaces in an ejb project? (For more than one Ejb project in an Enterprise application)
Question3: Ejb 3.0 no longer have the home and remote interfaces correct?
Why does the EntityManger get shared between two ejbprojects?
You can disable this sharing by isoloting Ejb jars if you don't want. If jboss open jboss-deployment-structure.xml and setting the property ear-subdeployments-isolated to true
If my Ejb2 project needs another persistence.xml for a different data
source, do I create another one or have it included in the existing
persistence.xml? will it also be shared ?
It purely depends on your use case,
if you have multiple datasources in your system then I would define my persistence.xml based
the way I package my beans accessing the Persistence Unit.
In case, if all of the entities belonging to both of the datasources are packaged together then I would define 2 persistence Unit in the same persistence.xml
if they are packaged in differently in 2 jars, then any of the following is a possibility
if beans accessing the entities serviced by the same
persistenceUnit/Datasource are packaged together then I would create
2 persistence.xml with associated PersistenceUnit in 2 jars
if isolation is set to false, then I can define my persistence.xml like
above or I would define 2 persistenceUnit together in a single
persistence.xml and would make sure that the jar with
Persistence.xml is deployed first
Does my Web1 project also get hold of the Entitymanager in the same
way?
Yes, you can get access to persistenceContext
Note: I assumed your app server to be JBoss
I have sessionbeans in Ejb1 project and their remote interfaces are
created in Web1 project but what is the best approach in exposing
these newly created Entities/Interfaces in an ejb project? (For more
than one Ejb project in an Enterprise application)
As far as my knowledge goes, it depends on your system Architecture/ Design. If I were you, I would have packaged my remote interfaces and Beans together in the same EJB-Jar and I would either use Business Delegate that lookup the EJB beans or as Remote interfaces are visible in the web, I would inject the same in the web layer and use it.
Ejb 3.0 no longer have the home and remote interfaces correct?
There are no interface called home & remote but the concept is still there in the form of annotations #Remote & #Local, which means you define your interfaces and you can declare either #Remote or #Local either at the interface level or at the Bean level.

#EntityListeners configured from container

I have a EntityListener that needs to be configurable (typical data source info: driver, user, password), but I´d like to avoid adding one more properties file to the project. Is there any way to retrieve from some standard configuration place such as web.xml? It seems that injection via #Resource will be only available in JPA 2.1 (I am using JPA 2.0).
UPDATE - to make this clear
In my entity bean, I have an annotation #EntityListeners(MyEntityListener.class). So MyEntityListener may have methods annotated with #PostPersist for example. When my entity bean is gonna be persisted, this method is called. What I want is to retrieve the data for MyEntityListener initialization without using another configuration file.
http://openjpa.apache.org/builds/2.2.1/apidocs/org/apache/openjpa/audit/Auditor.html does the trick. It works (my bad, it was a misconfiguration of mine). Actually it works pretty well.
<property name="openjpa.Auditor" value="com.acme.Auditor(param2=10,param2='hello')"/>

Passing db info to Hibernate at runtime?

The problem with hibernate is, you need to put the database info (username/pw etc) in an xml file. However, if you deploy your app on Amazon web services, e.g on Beanstalk, you get the db info passed in via System.getProperty("RDS_DATABASE_USER"), etc. The advantage is, if more instances of your app are created, the db info is passed on automatically, without having to manually edit config files.
Is there a way to pass the db info to hibernate at runtime? If not, is there another good ORM library for java, to which you can pass this info at runtime? I'm using MySQL.
As a matter of fact, the method PersistenceUtil.createEntityManagerFactory allows you to provide a properties map. Using this map you can provide the user name and password in dynamic way.
How you do this may well depend on what specific frameworks you are using.
Based on the tags in your question it is not clear if you are using Hibernate or if you are using OpenJPA.
The Open JPA documentation in the section Obtaining an EntityManagerFactory provides the list of properties you could use.
Map<String,String> properties = new HashMap<>();
properties.put("openjpa.ConnectionUserName", "userName");
properties.put("openjpa.ConnectionPassword", "password");
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPersistenceUnit",properties);
Hibernate supports a similar set of properties. Most probably you already have them in your persistence.xml file.
Some dependency injection frameworks, like Spring, don't even require a persistence.xml file and can read such properties dynamically from some other places, like environment variables.

Categories