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.
Related
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.
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>
I have the following implementation and would like some feedback as to whether it makes correct use of NHibernate for sessions and transactions.
public interface IUnitOfWork : IDisposable
{
ISession CurrentSession { get; }
void Commit();
void Rollback();
}
public class UnitOfWork : IUnitOfWork
{
private readonly ISessionFactory _sessionFactory;
private readonly ITransaction _transaction;
public UnitOfWork(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
CurrentSession = _sessionFactory.OpenSession();
_transaction = CurrentSession.BeginTransaction();
}
public ISession CurrentSession { get; private set; }
public void Dispose()
{
CurrentSession.Close();
CurrentSession = null;
}
public void Commit()
{
_transaction.Commit();
}
public void Rollback()
{
if (_transaction.IsActive) _transaction.Rollback();
}
}
Ninject binding
Bind<IUnitOfWork>().To<UnitOfWork>().InTransientScope();
Bind<ISessionFactory>().ToProvider<NHibernateSessionFactoryProvider>().InSingletonScope();
Bind<IRepository>().To<Repository>().InTransientScope();
Here is an example of the usage:
public class Repository : IRepository
{
private readonly ISessionFactory _sessionFactory;
public Repository(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
}
public void Add(IObj obj)
{
using (var unitOfWork = new UnitOfWork(_sessionFactory))
{
unitOfWork.CurrentSession.Save(obj);
unitOfWork.Commit();
}
}
}
In my previous implementation I would inject IUnitOfWork into my repository constructor like so
public Repository(IUnitOfWork unitOfWork)
{...
But the Dispose() method would not execute causing a subsequent call to throw this exception: "Cannot access a disposed object. Object name: 'AdoTransaction'."
First observation: your repository should not commit the unit of work. This defeats the whole point of the unit of work pattern. By immediately saving your changes inside the repository, you're "micro managing" the NHibernate Session.
The unit of work should be referenced higher up the stack, in your application/service layer. This allows you to have application code that performs several actions, potentially on different repositories, and still at the end commit everything at once.
The UnitOfWork class itself looks Ok, though you should ask yourself if you really need it. In NHibernate, the ISession IS your unit of work. Your UnitOfWork class does not seem to add a lot of value (especially since you're exposing the CurrentSession property anyway)
But you do need to think about it's lifetime. I think you have it wrong on this point. Session lifetime management depends on the type of application you're developing: in a web app, you typically want to have a unit of work per request (you might want to google on 'nhibernate session per request'). In a desktop app it's slightly more complicated, you will most of the time want a 'session per screen' or 'conversation per business transaction'.
I have a mostly CRUD type of application, and I implemented the Unit Of Work with Repository pattern, but couldn't really get away from the Session/Transaction split. Sessions and Transactions need different lifetimes. In the desktop world, a Session is usually "per-screen" and a Transaction is "per-user-action".
More information in this excellent article.
So what I ended up with was:
IUnitOfWork -> Wraps session, implements IDisposable
IAtomicUnitOfWork -> Wraps transaction, implements IDisposable
IRepository -> Provides Get, Save, Delete and query access
I made it so that you need an IUnitOfWork to build an IAtomicUnitOfWork and you need an IAtomicUnitOfWork to build an IRepository, so that enforces proper transaction management. That's really all I gained by implementing my own interfaces.
As jeroenh said, you are almost just as well to use ISession and ITransaction but in the end I felt a little better writing all my code against an interface that I defined.
An important part of the answer lies in what you want your transaction sizes to be. Right now (as jeroenh has indicated) the transaction is per method invocation on your repository. This is very small and probably not needed. I created an ASP.MVC application and it uses a transaction size that included everything from a single http request. This could be multiple database reads/updates. I am using the same unit of work and Ninject for IOC. Take a look, maybe something will help with your issues:
http://bobcravens.com/2010/06/the-repository-pattern-with-linq-to-fluent-nhibernate-and-mysql/
http://bobcravens.com/2010/07/using-nhibernate-in-asp-net-mvc/
http://bobcravens.com/2010/09/the-repository-pattern-part-2/
http://bobcravens.com/2010/11/using-ninject-to-manage-critical-resources/
Hope this helps.
Bob
I'm trying to write my Domain Model as persistence-ignorant as possible. The only thing I'm doing right now is marking every property and method virtual, as NHibernate requires that for lazy-loading.
In my domain model assembly I define some repository interfaces:
public interface IRepository<TEntity> where TEntity : EntityBase {
TEntity Get(int id);
/* ... */
}
public interface IProductRepository : IRepository<Product> { ... }
Then I have a data assembly. This one will reference NHibernate, it knows about its existence. This is the assembly that implements those repository interfaces:
public abstract class Repository<TEntity> : IRepository<TEntity> {
public TEntity Get(ind id) { ... }
/* ... */
}
public class ProductRepository : Repository<Product>, IProductRepository {
/* ... */
}
and so on.
Now I wanted to implement a transaction functionality to my repositories. To do so, I would add a BeginTransaction method on my IRepository interface. However, I cannot define its return type as NHibernate.ITransaction, since I want to keep the domain model persistence-ignorant, and not be forced to reference NHibernate's assembly from my domain model assembly.
What would you do?
Would you simply implement a void BeginTransaction(), a void Commit(), and a void RollBack() methods on the interface, and let the repository implementation manage the ITransaction object internally?
Or would you find a way to expose the ITransaction object to let the client manage the transaction directly with it, instead of using repository's methods?
Thanks!
You can take a look at the Sharp Architecture which has already implemented everything you talk about, including generic repositories with transactions support. The solution there is that IRepository has DbContext property which encapsulates transactions (it's actually an interface).
This is the first of the options that you described (custom transactions interface which hides NHibernate). And it works well.
I guess you can even re-use S#arp code regardless if you intend to use the full framework.
IMO Transactions should always start and end in business logic, in other words the transaction should start in the service layer not the repository layer and the repository should enlist it's self in the transaction, ideally this would be done implicitly.
Now if you're using NH then if your service and repositories share the same 'session' (which they should) then you can call 'BeginTransaction' in the service layer and commit or roll back as required:
Eg, imagine this a method on a service:
public void RegisterCustomer(Customer customer)
{
try
{
using(var transaction = _session.BeginTransaction())
{
_customerRepository.Save(customer);
_customerSurveyRepository.Save(customerSurvey);
// DO What ever else you want...
transaction.Commit();
}
}
catch (Exception exn)
{
throw new AMException(FAILED_REGISTRATION, exn);
}
}
How the repositories obtain a reference to the same Session can be solved by injecting in the constructors or by using a the SessionFactory to obtain the current session...
An advantage of an IoC container is that you can swap in a mock service at the bottom of your object graph. However this seems much harder to do in Spring.Net than in other IoC Containers. Here's some code that does it in Unity and has Spring.Net code;
namespace IocSpringDemo
{
using Microsoft.Practices.Unity;
using NUnit.Framework;
using Spring.Context;
using Spring.Context.Support;
public interface ISomeService
{
string DoSomething();
}
public class ServiceImplementationA : ISomeService
{
public string DoSomething()
{
return "Hello A";
}
}
public class ServiceImplementationB : ISomeService
{
public string DoSomething()
{
return "Hello B";
}
}
public class RootObject
{
public ISomeService SomeService { get; private set; }
public RootObject(ISomeService service)
{
SomeService = service;
}
}
[TestFixture]
public class UnityAndSpringDemo
{
[Test]
public void UnityResolveA()
{
UnityContainer container = new UnityContainer();
container.RegisterType<ISomeService, ServiceImplementationA>();
RootObject rootObject = container.Resolve<RootObject>();
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void UnityResolveB()
{
UnityContainer container = new UnityContainer();
container.RegisterType<ISomeService, ServiceImplementationB>();
RootObject rootObject = container.Resolve<RootObject>();
Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
}
[Test]
public void SpringResolveA()
{
IApplicationContext container = ContextRegistry.GetContext();
RootObject rootObject = (RootObject)container.GetObject("RootObject");
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void SpringResolveB()
{
// does not work - what to do to make this pass?
IApplicationContext container = ContextRegistry.GetContext();
RootObject rootObject = (RootObject)container.GetObject("RootObject");
Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
}
}
}
For the benefit of Spring, the following needed to be in the App.config file. Clearly this only serves the first spring test, and not the second. Can you put multiple spring configurations in the config file? If so, what is the syntax and how do you access them? Or is there another way to do this?
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<object name="RootObject" type="IocSpringDemo.RootObject, IocDemo" autowire="constructor" />
<object name="service" type="IocSpringDemo.ServiceImplementationA, IocDemo" autowire="constructor" />
</objects>
</spring>
Update
Here is a partial answer based at code at the links that Marko Lahma gave to Mark Pollack's blog. I have the above tests passing, with the following code:
public static class SpringHelper
{
public static T Resolve<T>(this IApplicationContext context, string name)
{
return (T)context.GetObject(name);
}
public static void RegisterType<T>(this GenericApplicationContext context, string name)
{
context.RegisterType(name, typeof(T));
}
public static void RegisterType(this GenericApplicationContext context, string name, Type type)
{
IObjectDefinitionFactory objectDefinitionFactory = new DefaultObjectDefinitionFactory();
ObjectDefinitionBuilder builder = ObjectDefinitionBuilder.RootObjectDefinition(objectDefinitionFactory, type);
builder.SetAutowireMode(AutoWiringMode.AutoDetect);
context.RegisterObjectDefinition(name, builder.ObjectDefinition);
}
}
...
[Test]
public void SpringResolveA()
{
GenericApplicationContext container = new GenericApplicationContext();
container.RegisterType<RootObject>("RootObject");
container.RegisterType<ServiceImplementationA>("service");
RootObject rootObject = container.Resolve<RootObject>("RootObject");
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void SpringResolveB()
{
GenericApplicationContext container = new GenericApplicationContext();
container.RegisterType<RootObject>("RootObject");
container.RegisterType<ServiceImplementationB>("service");
RootObject rootObject = container.Resolve<RootObject>("RootObject");
Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
}
This raises a few questions to me:
I want to integrate this technique into existing code that uses the usual container. Why do I have to use a different container type, GenericApplicationContext in this case? What if I want to read data into this object from the existing spring config in app.config or web.config? Would it work as the usual context? Could I then write data over these registrations with code?
How can I specify that ISomeService is to be created as a singleton? I don't mean supply a singleton instance to the container, but the container to create the instance, resolving its constructor, and use it when that type is needed.
how can I do the equivalent of container.RegisterType<ISomeService, ServiceImplementationA>(); ? I want to register type mappings to use in all cases where that type is needed by a constructor.
What exactly does container.RegisterType<ServiceImplementationA>("service"); do? It seems to register ServiceImplementationA as the implementation of ISomeService but ISomeServiceis never mentioned, so there could be ambiguity. e.g. what if ServiceImplementationA implemented more than one interface.
What is the string name given to the registration for? It won't work with en empty string, but it doesn't seem to matter what it is.
Am I trying to use spring in a way that it just does not work? I'm trying to use it like other IoC containers, but it's not quite working.
Adding as new answer trying to address the open points...
I want to integrate this technique
into existing code that uses the usual
container. Why do I have to use a
different container type,
GenericApplicationContext in this
case? What if I want to read data into
this object from the existing spring
config in app.config or web.config?
Would it work as the usual context?
Could I then write data over these
registrations with code?
Spring has concrete application context implementations for different kind of initialization tactics. The most common ones to use are GenericApplicationContext (manual), XmlApplicationContext (XML files) and WebApplicationContext (very much like XmlApplicationContext but tailored for web use). They all implement common interface: IApplicationContext which is the preferred way to access these containers.
Unfortonately altering registrations with code usually means that you need to use the specific sub-class directly. With GenericApplicationContext and StaticApplicationContext this is quite natural but XmlApplicationContext is usually considered to be XML only and this ways "fixed" to XML definition.
How can I specify that ISomeService is
to be created as a singleton? I don't
mean supply a singleton instance to
the container, but the container to
create the instance, resolving its
constructor, and use it when that type
is needed.
Your SpringHelper does just that, by default all objects in Spring are singletons. You could alter this behavior by calling ObjectDefinitionBuilder's SetSingleton method with false.
how can I do the equivalent of
container.RegisterType(); ? I want to
register type mappings to use in all
cases where that type is needed by a
constructor.
Spring uses object names (ids) to distinct between different implementations. So if you want to get specific type to serve a specific instance in case that there are many alternatives you should refer to this specific instance by name. If you are using autowiring and your object has dependency to interface ISomeService and there's only one object registered that implements it, the autowiring can set it without ambiguity.
What exactly does
container.RegisterType("service");
do? It seems to register
ServiceImplementationA as the
implementation of ISomeService but
ISomeServiceis never mentioned, so
there could be ambiguity. e.g. what if
ServiceImplementationA implemented
more than one interface.
Continuing from previous answer, this registers singleton of type ServiceImplementationA with name "service". This object comes autowiring candidate with all it's implemented interfaces (and with it's concrete type of course).
What is the string name given to the
registration for? It won't work with
en empty string, but it doesn't seem
to matter what it is.
It matters a great deal as explained earlier. The name is unique id within that context (parent context could have object with same name) and can be used to access specific object registrations. In short where other frameworks may associate a type as key to object registration, Spring uses name.
That's a bit apples and oranges comparison as the unit test uses code configuration for Unity and XML (app.config) configuration for Spring.NET.
If you go the XML route, then you can either comment out old implementation A and define the B implementation as the one to use - that what's configuration is all about right? Other option is to have dedicated XML files for each scenario (configuration setup) and include them via context's resource definitions (you have inline resource now). Other options include file system and assembly, see the web configuration section in Spring.NET's manual for a nice example.
If you go the code configuration route I would suggest to check Spring.NET Recoil and upcoming CodeConfig.