using JDBC with persistence.xml - java

I am building a framework that manage the access to the database.
the framework getting tasks from the user and handle a connection pooling that manage the access to the database. the user just send me SQL commands.
One of the feature that i would like to support is working with JPA, in this case i will provide entity manager. in some cases i would like to provide JDBC access as well as JPA access. the arguments for the database are written in XML file.
so for JPA i need to write the property in persistence.xml so it will be not so smart to write again the same arguments for JDBC. do you know if i can get the arguments of the database from persistence.xml, do you know if there is a source code that do it. or should i parse persistence.xml by myself?

Do you know if I can get the arguments of the database from persistence.xml, do you know if there is a source code that do it. Or should I parse persistence.xml by myself?
I'm not aware of anything in the standard JPA API allowing to retrieve the driver class name, the jdbc url, the username and password.
Second problem, the keys for those properties are not standardized in JPA 1.0. For example, Hibernate will use:
<property name="hibernate.connection.driver_class" value=""/>
<property name="hibernate.connection.url" value=""/>
<property name="hibernate.connection.username" value=""/>
<property name="hibernate.connection.password" value=""/>
While EclipseLink will use:
<property name="eclipselink.jdbc.driver" value=""/>
<property name="eclipselink.jdbc.url" value=""/>
<property name="eclipselink.jdbc.user" value=""/>
<property name="eclipselink.jdbc.password" value=""/>
This may make the parsing fragile.
If this is an option, maybe you could use a properties file to store both the provider specific keys and the values (I'd recommend using the standardized JPA 2.0 properties as keys). For example:
# keys for JPA
javax.persistence.jdbc.driver = hibernate.connection.driver_class
javax.persistence.jdbc.url = hibernate.connection.url
javax.persistence.jdbc.user = hibernate.connection.username
javax.persistence.jdbc.password = hibernate.connection.password
# values common to JPA and JDBC
driver = org.h2.Driver
url = jdbc:h2:mem:test
username = scott
password = tiger
And use Persistence.createEntityManagerFactory(String, Map) and pass a Map that you'll feed with the properties from the file to create the EntityManagerFactory:
Map map = new HashMap();
map.put(...);
...
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPu", map);

Related

CreateArray fails with Unsupported feature : createArrayof in mule

dbCreateArray function fails while using Oracle DB with c3p0 connection pooling with error, java.sql.SQLException: Unsupported feature I am using below method
#[dbCreateArray(oracle_Configurtion, <USER_DEFINED_DATA_TYPE_NAME_AS_IN_ORACLE>, Object[])]
I am using mule EE 3.9, oracle 12.2.0 and c3p0 0.9.5.2
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value = "oracle.jdbc.pool.OracleDataSource" />
<property name="jdbcUrl" value = "${db.url}" />
<property name="user" value = "${db.username}" />
<property name="password" value = "${db.password}" />
<property name="initialPoolSize" value = "${pool.initialSize}" />
</bean>
I Have seen this blog he suggested switch to oracle ucp pool but is there any way to fix this issue when using c3p0 pool.
https://help.mulesoft.com/s/article/dbCreateArray-function-failing-with-DB-connection-pooling
Oracle does not support the JDBC4-standard createArrayOf method.
Instead you must call a proprietary createARRAY method.
If you were writing code directly, it's be no problem to unwrap the c3p0 Connection to the underlying Oracle Connection and call the proprietary method. However, it looks like you are working through a higher-level language that is presumably being translated to standard JDBC methods. Unless you can get under the covers of how that conversion is done, it probably won't be easy to get this higher-level language call to work.
It look's like Oracle's own UCP has built-in an Oracle-specific workaround, but c3p0 does not include such a workaround, alas.

How to dynamically change database password used by a DataSource, which is in turn used by a spring transaction manager

How can I dynamically (at run time) change the DB username and password used by a DataSource when using a Spring transaction manager?
We are using Spring and have a BasicDataSource and a TransactionManager defined as follows for handling database connections and transactions:
<bean id="myDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="url" ref="dbUrl"/>
<property name="username" ref="someUsername"/>
<property name="password" ref="somePassword"/>
<property name="driverClassName" value="org.postgresql.Driver" />
...
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="myDataSource" />
<tx:annotation-driven transaction-manager="transactionManager" />
We need to support dynamically changing the password that we are using at runtime. Note that I am not trying to change the password in the DB; that has already happened outside of the application. I am trying to tell my application to switch passwords that it is using to connect to the DB.
I tried extending BasicDataSource and calling setUsername() and setPassword(), but it appears that changing the username and password have no effect. I can see by looking into the implementation of BasicDataSource that the username and password appear to only be used when it initially constructs the connection pool.
I then found org.apache.commons.dbcp2.datasources.SharedPoolDataSource and thought that would be the answer to my problems. But it looks like DataSourceTransactionManager takes a javax.sql.DataSource, which surprisingly SharedPoolDataSource is not.
I can't find any other transaction managers that would take a SharedPoolDataSource or even a javax.sql.ConnectionPoolDataSource.
Is there a way to use a transaction manager and a connection pool and dynamically change the DB password that is used?

Lazy init for activemq datasource

I was wondering if there is any way for lazy init of activemq persistence. The problem is that I don't want to specify user and password of the database beforehand, but rather let user enter these values after application's initialization. So, for example user starts application and then is required to enter database username and password. After he does so, the application initializes activemq persistence using database connection provided by user.
<amq:persistenceFactory>
<amq:journalPersistenceAdapterFactory journalLogFiles="4" dataDirectory="./journal-data" dataSource="#postgre-ds">
<amq:statements>
<amq:statements binaryDataType="VARCHAR(250)"/>
</amq:statements>
</amq:journalPersistenceAdapterFactory>
</amq:persistenceFactory>
wherere postgre-ds
<bean id="postgre-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:someURL"/>
<property name="username" value="username"/>
<property name="password" value="pa55w0rd"/>
<property name="maxActive" value="200"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
so I want first get values for username and password and after that initialize persistence. Thanks )
The whole idea with spring is to wire up these things at startup, which covers 99% of the usecases.
There is nothing magical about it. It's just plain java objects anyway. If you need more control over the life cycle and input parameters, then go ahead and do the things manually.
DataSource ds = new BasicDataSource();
ds.setUsername( getInput() );
// ... set all parameters needed
JournalPersistenceAdapterFactory factory = new JournalPersistenceAdapterFactory();
factory.setDataDirectoryFile(data);
//.. set all parameters needed
BrokerService broker = new BrokerService();
broker.setPersistenceFactory(factory);
broker.addConnector(ActiveMQConnectionFactory.DEFAULT_BROKER_BIND_URL);
// More config goes here
broker.start();

configuring infinispan in jboss 7 programmatically

is there a way i can take away the configuration of infinispan completely from the standalone.xml and have the configuration like the following in my persistence.xml :
<property name="hibernate.cache.infinispan.entity.strategy" value= "LRU" />
<property name="hibernate.cache.infinispan.entity.eviction.max_entries" value= "1000"/>
<property name="hibernate.cache.infinispan.entity.eviction.strategy" value= "LRU"/>
<property name="hibernate.cache.infinispan.entity.eviction.wake_up_interval" value= "2000"/>
<property name="hibernate.cache.infinispan.entity.eviction.max_entries" value= "5000"/>
<property name="hibernate.cache.infinispan.entity.expiration.lifespan" value= "60000"/>
<property name="hibernate.cache.infinispan.entity.expiration.max_idle" value= "30000"/>
thanks in advance
I don't know your use case but there is a possibility to configure Infinispan CacheManagers and Caches programmatically using fluent builder API. It means no need of standalone.xml and even no need of configuration for Infinispan in persistence.xml.
For more information see: https://docs.jboss.org/author/display/ISPN/Configuring+cache+programmatically
In this tutorial I can see configuration of CacheManager like this (which can be confusing now):
EmbeddedCacheManager manager = new DefaultCacheManager("my-config-file.xml");
You can configure it entirely programmatically too without any input xml file, for example:
GlobalConfigurationBuilder global = new GlobalConfigurationBuilder();
global.transport().defaultTransport();
global.globalJmxStatistics().enable();
manager = new DefaultCacheManager(global.build());

get hibernating mapping from application code

Is there a way to get the hibernate mapping from within my application code?
for example, for the below mapping, I want to return createdDate given created_date from my application.
<property
name="createdDate"
type="java.lang.String"
column="created_date"
length="45"
/>
You probably could do so by using Configuration to get the Property you need, for example:-
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
Property property = configuration.getClassMapping("EntityName").getProperty("createdDate");
... // use the API from Property
Here's the javadoc for Property where you can get the information you need.

Categories