I need to switch the database dynamically on my application in runtime. So a do this class to producer my own entitymanager:
#ApplicationScoped
public class ApplicationResources {
#PersistenceContext
private EntityManager entityManager;
#Produces
#Default
#RequestScoped
public EntityManager produceEntityManager() {
Map<Object, Object> props = new HashMap<Object, Object>();
props.put(PersistenceUnitProperties.JTA_DATASOURCE, DATABASENAME);
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("PU", props);
return entityManagerFactory.createEntityManager();
}
public void dispose(#Disposes EntityManager entityManager) {
entityManager.close();
}
}
So I use #Inject to get a entityManager and do all the persistence operations on database. I have two problems:
When I change the jta-data-source the Eclipselink takes a lot of time to connect. And its run all validations again (like in application startup). I need to change connection more fast.
I can't save or update objects when I'm logged in. I can update and get them all (objects) just it.
I used this approach for seeming simpler. Because my application is already quite large. And now I need multiple clients in other databases. Help me there .. maybe this could be very wrong, but the multitenancy approaches with eclipselink seemed very complex. I need the idea of multitenancy with a bunch of different data. But if I could only change the connected database when and where I wanted, it would solve a lot.
I am using the Wildfly Server, CDI, Eclipselink, JTA and JSF.
Thank you for your help.
Related
I am using glassfish server with multiple jdbc connection pools. I want to have EntityManagerFactories for every jdbc connection.
Using the code
Map props = new HashMap();
props.put(PersistenceUnitProperties.JTA_DATASOURCE, <my jdbc datasource>);
Persistence.createEntityManagerFactory(<persistence unit name>, props);
Works fine but I cannot combine it with the UserTransation to have transaction begin and commit, rollback.
Furthermore entityManager.getTrasnaction().begin, commit, rollback don’t work (I get records persisted in the database when an error occurs).
Things work great when I use UserTrasnaction and EntityManager injected with
#Resource
UserTransaction utx1;
#PersistenceContext(unitName = <persistence unit name>)
private EntityManager em1;
With the injection the utx1.begin(), utx1.commit() controls the entityManager perfectly!
But the problem is that I cannot use my multiple jdbc connection pools that i have set up on my server.
So my question is:
Can I do programmatically what this injection does?
#Resource
UserTransaction utx1;
#PersistenceContext(unitName = <persistence unit name>)
private EntityManager em1;
Thanx!
I have tried this, but it doesnt work
#Resource
UserTransaction utx1;
#PersistenceContext(
properties = {#PersistenceProperty(name=PersistenceUnitProperties.JTA_DATASOURCE, value="ORCLH_MARMA")},
unitName = "MINLO")
private EntityManager em1;
You should use CDI #Qualifiers and EntityProducers to do that, and use the persistence.xml file to define your multiple persistence-units (with the same entities), provided they are prepared to do that.
First things first: define as many datasource qualifiers as needed
#Qualifier
#Retention(RUNTIME)
#Target({METHOD, FIELD, PARAMETER, TYPE})
public #interface MainDatabase {
}
and a second one
#Qualifier
#Retention(RUNTIME)
#Target({METHOD, FIELD, PARAMETER, TYPE})
public #interface SecondaryDatabase {
}
Then create a EntityManager producer using proper datasources:
#ApplicationScoped
public EntityManagerProducer {
#Produces #RequestScoped
#MainDatabase
#PersistenceContext(unitName = "main-pu-01")
private EntityManager mainEntityManager;
#Produces #RequestScoped
#SecondaryDatabase
#PersistenceContext(unitName = "secondary-pu-01")
private EntityManager secondaryEntityManager
}
In your persistence.xml, define both persistence units for the same entities, but with different names and data-sources:
<persistence version="2.1"...>
<persistence-unit name="main-pu-01" transaction-type="JTA">
<jta-data-source>jdbc/maindatasource</jta-data-source>
...
</persistence-unit>
<persistence-unit name="secondary-pu-01" transaction-type="JTA">
<jta-data-source>jdbc/secondarydatasource</jta-data-source>
...
</persistence-unit>
</persistence>
Then, in your EJBs or CDI beans, inject the desired entity manager to perform your ops:
#RequestScoped
public abstract class EntityController<E> {
#Inject #MainDatabase
private EntityManager mainEM;
#Inject #SecondaryDatabase
private EntityManager secondaryEM;
public E doSomethingInMain(E e) {
return mainEM.something...
}
public E doSomethingInSecondary(E e) {
return secondaryEM.something...
}
}
Be aware that #Transactional operations may not propagate instantly between EntityManagers if they share the same database, except if you tune caches properly.
I don't know why you need to use different users for each datasource, so I suggest you check if you aren't incurring in a xyproblem.
I am looking for a way to dynamically select the correct dependency during runtime using google guice.
My usecase is a kotlin application which can work with either sqlite or h2 databases depending on the configuration file provided.
The file is read when the application is executed and if the database is not found, the correct one is created and migrated into.
My database structure contains the Database (Interface), H2Database: Database, SQLiteDatabase: Database and the module binding class which looks like this:
class DatabaseModule: KotlinModule() {
override fun configure() {
bind<Database>().annotatedWith<configuration.H2>().to<H2Database>()
bind<Database>().annotatedWith<configuration.SQLite>().to<SQLiteDatabase>()
}
}
So far, with SQlite alone, I would simply request the dependency using:
#Inject
#SQLite
private lateinit var database: Database
How would I make this selection during runtime?
Without knowing too much about the specific of your code, I'll offer three general approaches.
(Also, I have never used Kotlin. I hope Java samples are enough for you to figure things out.)
First Approach
It sounds like you need some non-trivial logic to determine which Database implementation is the right one to use. This is a classic case for a ProviderBinding. Instead binding Database to a specific implementation, you bind Database to a class that is responsible providing instances (a Provider). For example, you might have this class:
public class MyDatabaseProvider.class implements Provider<Database> {
#Inject
public MyDatabaseProvider.class(Provider<SQLiteDatabase> sqliteProvider, Provider<H2Database> h2Provider) {
this.sqliteProvider = sqliteProvider;
this.h2Provider = h2Provider;
}
public Database get() {
// Logic to determine database type goes here
if (isUsingSqlite) {
return sqliteProvider.get();
} else if (isUsingH2) {
return h2Provider.get();
} else {
throw new ProvisionException("Could not determine correct database implementation.");
}
}
}
(Side note: This sample code gets you a new instance every time. It is fairly straightforward to make this also return a singleton instance.)
Then, to use it, you have two options. In your module, you would bind Database not to a specific implementation, but to your DatabaseProvider. Like this:
protected void configure() {
bind(Database.class).toProvider(MyDatabaseProvider.class);
}
The advantage of this approach is that you don't need to know the correct database implementation until Guice tries to construct an object that requires Database as one of its constructor args.
Second Approach
You could create a DatabaseRoutingProxy class which implements Database and then delegates to the correct database implementation. (I've used this pattern professionally. I don't think there's an "official" name for this design pattern, but you can find a discussion here.) This approach is based on lazy loading with Provider using the Providers that Guice automatically creates(1) for every bound type.
public class DatabaseRoutingProxy implements Database {
private Provider<SqliteDatabse> sqliteDatabaseProvider;
private Provider<H2Database> h2DatabaseProvider;
#Inject
public DatabaseRoutingProxy(Provider<SqliteDatabse> sqliteDatabaseProvider, Provider<H2Database> h2DatabaseProvider) {
this.sqliteDatabaseProvider = sqliteDatabaseProvider;
this.h2DatabaseProvider = h2DatabaseProvider;
}
// Not an overriden method
private Database getDatabase() {
boolean isSqlite = // ... decision logic, or maintain a decision state somewhere
// If these providers don't return singletons, then you should probably write some code
// to call the provider once and save the result for future use.
if (isSqlite) {
return sqliteDatabaseProvider.get();
} else {
return h2DatabaseProvider.get();
}
}
#Override
public QueryResult queryDatabase(QueryInput queryInput) {
return getDatabase().queryDatabase(queryInput);
}
// Implement rest of methods here, delegating as above
}
And in your Guice module:
protected void configure() {
bind(Database.class).to(DatabaseRoutingProxy.class);
// Bind these just so that Guice knows about them. (This might not actually be necessary.)
bind(SqliteDatabase.class);
bind(H2Database.class);
}
The advantage of this approach is that you don't need to be able to know which database implementation to use until you actually make a database call.
Both of these approaches have been assuming that you cannot instantiate an instance of H2Database or SqliteDatabase unless the backing database file actually exists. If it's possible to instantiate the object without the backing database file, then your code becomes much simpler. (Just have a router/proxy/delegator/whatever that takes the actual Database instances as the constructor args.)
Third Approach
This approach is completely different then the last two. It seems to me like your code is actually dealing with two questions:
Does a database actually exist? (If not, then make one.)
Which database exists? (And get the correct class to interact with it.)
If you can solve question 1 before even creating the guice injector that needs to know the answer to question 2, then you don't need to do anything complicated. You can just have a database module like this:
public class MyDatabaseModule extends AbstractModule {
public enum DatabaseType {
SQLITE,
H2
}
private DatabaseType databaseType;
public MyDatabaseModule(DatabaseType databaseType) {
this.databaseType = databaseType;
}
protected void configure() {
if (SQLITE.equals(databaseType)) {
bind(Database.class).to(SqliteDatabase.class);
} else if (H2.equals(databaseType)) {
bind(Database.class).to(H2Database.class);
}
}
}
Since you've separated out questions 1 & 2, when you create the injector that will use the MyDatabaseModule, you can pass in the appropriate value for the constructor argument.
Notes
The Injector documentation states that there will exist a Provider<T> for every binding T. I have successfully created bindings without creating the corresponding provider, therefore Guice must be automatically creating a Provider for configured bindings. (Edit: I found more documentation that states this more clearly.)
Need some help.
I have a .netcore 2.1 API which is secured via Azure Bearer token from its clients. I am wanting to collect user information from the bearer token of clients and store it in a SQL database so that I can tag entries within the database if they are being added/deleted/edited etc. For the SQL table joins I therefore need the user imformation in SQL.
Below is my implementation of a Cache Service using IDistributedCache. On Init I am trying to load all currently stored users from the SQL DB in to the cache, then added to it when new users connect in.
To capture the connections across the entire API I was using a TypeFilterAttribute to execute OnActionExecuting.
The problem is that the CacheService is a singleton and is calling the UserRepository - which is scoped. This isn't allowed.
Any thoughts?
startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
// Context
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.TryAddSingleton<CacheService>();
// Repositories
services.TryAddScoped<IUserRepository, UserRepository>();
services.AddDistributedMemoryCache();
services.AddMvc(
opts => opts.Filters.Add(new HttpInterceptor())
)
...
CacheService.cs
public class CacheService
{
private readonly IDistributedCache _cache;
private readonly IUserRepository _userRepository;
public CacheService(
IDistributedCache cache,
[FromServices] IUserRepository userRepository
)
{
_cache = cache;
_userRepository = userRepository;
// Populate cache from DB
var users = _userRepository.GetAll().Result;
foreach (var u in users)
{
if (_cache.GetAsync(u.Username).Result == null)
{
var profileSerialised = JsonConvert.SerializeObject(UserToUserProfile(u));
var entry = Encoding.UTF8.GetBytes(profileSerialised);
_cache.SetAsync(u.Username, entry, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30) });
}
}
}
HttpInterceptor.cs
public class HttpInterceptor : TypeFilterAttribute
{
public HttpInterceptor() : base(typeof(IHttpInterceptor))
{
}
private class IHttpInterceptor : IActionFilter
{
private readonly CacheService _cache;
private readonly IUserRepository _userRepository;
public IHttpInterceptor(
CacheService cache,
IUserRepository userRepository)
{
_cache = cache;
_userRepository = userRepository;
}
public void OnActionExecuting(ActionExecutingContext context)
{
if (context.HttpContext.User.Identity.IsAuthenticated)
{
this._cache.GetUserProfile(context.HttpContext.User.Identity.Name);
}
}
First, you're looking at this upside-down and backwards. Having some service add stuff to the cache and then having other code just assume that stuff is in the cache ready to go is a recipe for disaster. Instead, have your dependent code literally request the data it needs, and then, if you want to cache it, do it the method that fetches the data. That way your app code remains agnostic about where the data is coming from; it just calls a method and it gets the data it wants. Under the hood, it's either pulled from the database or the cache, depending on which is available/preferred.
Your cache service has serious issues anyways. First, it should not be a singleton in the first place. There's no reason for it to be, and since you're dealing with scoped services inside, you're only making things more difficult than they need to be. Second, you should never ever utilize I/O in a constructor. Only simple variable/prop initialization should be done there. Anything that requires actual work should go into a method. If you truly want to do something on initialization, then you should implement a factory pattern. For example, you might have something like a CacheServiceFactory with a Create method that returns a fully instantiated CacheService including calling any methods that do actual work.
With the disclaimers aside, in general, to use a scoped service in a singleton, you must create a scope. This must be done every time you want to utilize the service; you cannot persist the service to an ivar on your singleton class. Simply, you inject IServiceProvider into your class, which is itself singleton-scoped, so you'll have no problems with that. Then, when you need to utilize a scoped service:
using (var scope = provider.CreateScope())
{
var repo = scope.ServiceProvider.GetRequiredService<IUserRepository>();
// do something with repo
}
This is called the service locator anti-pattern. It's called such because it's something you should really avoid doing. Sometimes that's no always possible. However, more often than not, you can simply design things in a different way: such as making the service scoped itself.
I am new to Spring AOP and AspectJ but the simplicity they can provide makes me want to use them.
The questions is: I have two projects, one is a spring boot application server and the other one contains all the utilities functions core. I want to implement logging aspect in both projects and here is what I did:
server
#Aspect
#Component
public class MethodLoggingAspect {
#Around("#annotation(logExecutionTime)")
public Object methodLog(ProceedingJoinPoint joinPoint, LogExecutionTime logExecutionTime) throws Throwable {
final Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
final long start = System.nanoTime();
Object proceed = joinPoint.proceed();
final long end = System.nanoTime();
logger.info("method={}, millis={}", joinPoint.getSignature().toShortString(), TimeUnit.NANOSECONDS.toMillis(end - start));
return proceed;
}
}
#Configuration
#EnableAspectJAutoProxy
#ComponentScan
public class BeanConfiguration {
}
core
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface LogExecutionTime {
}
I use the annotation LogExecutionTime both in core and application server these are two different jars and server has dependency core. I expect the aspect will work in both two parts when I run server, but the fact is that only methods in server have the aspect weaved in.
I also tried to define the aspect in core and use aspectJ to do compile-time weaving. But there is Immutable library in core, which will throw a compile time error when I use aspectj-maven-plugin.
Can anyone help me with it? Thanks!
Does anybody know if it is possible to control the names of the types generated through Castle DynamicProxy? I was hoping to take advantage of the ability to persist the assembly generated by Castle to add some additional classes with some specific functionality to my project, but I would like to be able to control the names of these generated proxy types. Any help would be greatly appreciated.
I actually plan to persist instances of these classes as well as instances of the original classes that are the sources of the proxies with NHibernate. So, I need these names to be consistent across multiple generations of the assembly.
I did some interesting digging. Specifying proxy names appears to be possible using an INamingScope, but it is far from straightforward to get the INamingScope wedged in. You would need to create your own ProxyFactoryFactory, which would create a ProxyFactory identical to NHibernate.ByteCode.Castle.ProxyFactory, except it would initilize ProxyGenerator:
public class CustomProxyFactory : AbstractProxyFactory {
private static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator(new CustomProxyBuilder());
// remainder of code is identical
}
public class CustomProxyBuilder : DefaultProxyBuilder {
public CustomProxyBuilder() : base(new CustomModuleScope()) {}
}
public class CustomModuleScope : ModuleScope {
public CustomModuleScope() : base(false, false, new CustomNamingScope(), DEFAULT_ASSEMBLY_NAME, DEFAULT_FILE_NAME, DEFAULT_ASSEMBLY_NAME, DEFAULT_FILE_NAME) {}
}
public class CustomNamingScope : INamingScope {
public CustomNamingScope() {}
private CustomNamingScope(INamingScope parent) {
ParentScope = parent;
}
public string GetUniqueName(string suggestedName) {
// your naming logic goes here
}
public INamingScope SafeSubScope() {
return new CustomModuleScope(this);
}
public INamingScope ParentScope { get; private set; }
}
I honestly haven't tried running or compiling any of this. Just digging through the NHibernate and Castle.Core source code. Hopefully it gives you some ideas...
Take a look at the ProxyGenerators project in NHContrib. It allows you to pre-generate NHibernate's lazy loading proxies.
http://nhforge.org/wikis/proxygenerators10/default.aspx
Whether you use the ProxyGenerators or not, you integrate your custom proxies into NHibernate via the Proxy Factory Factory. In hibernate.cfg.xml:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="proxyfactory.factory_class">YOUR_PROXY_FACTORY_FACTORY</property>
</session-factory>
</hibernate-configuration>