I've created a sample application based on the JBoss Kitchensink example. This application records Entities using CDI Beans. I've found quite easy to store a new Entities using JPA + firing the Observer on the newly created Entity:
#Inject
private Event<MyEntity> propEventSrc;
public void put(MyEntity p){
em.persist(p);
propEventSrc.fire(p);
}
However I cannot find a way to fire the event in case the user wants to delete all records. In other words:
public void delete(){
Query query = em.createQuery("delete FROM MyEntity ");
query.executeUpdate();
// I need to fire an event here so that the List of MyEntities from the Producer class gets updated
}
I've tried with the notifyAll() method of the propEventSrc but that does just produce Exceptions, Any idea how to solve this issue ?
Thanks
Max
if you want to fire event for every entity that gets deleted, best approach would be to add #PostRemove handler to entity in question and add code that fires event.
some examples http://en.wikibooks.org/wiki/Java_Persistence/Advanced_Topics
you might have some problems with injecting CDI objects into EntityListener but you can workaround this(until JPA 2.1) as described in CDI injection in EntityListeners
Related
We are considesing using BreezeJS as analogous solution to our current WCF Ria Services + Silverlight pair. In WCF Ria Services we have client DataContext containing EntitySet instances which get populated with queries.
For example, there we might have three methods on our DomainService described below. Assume also that User is linked to Order as 1-to-many:
public IEnumerable<User> GetFirst10Users(){
//retrieve from DB with EF
return ObjectContext.Users.OrderBy(u => u.Id).Take(10);
}
public IEnumerable<User> GetLast10Users(){
//retrieve from DB with EF
return ObjectContext.Users.OrderByDesc(u => u.Id).Take(10);
}
public IEnumerable<Order> GetOrders(){
//retrieve from DB with EF
return ObjectContext.Orders;
}
As a result we'll have something like this generated for us on client-side:
public class Context{
public EntitySet<User> Users {...};
public EntitySet<Order> Orders {...};
public EntityQuery<User> GetFirst10UsersQuery(){
}
public EntityQuery<User> GetLast10UsersQuery(){
}
public EntityQuery<Orders> GetOrdersQuery(){
}
}
If we execute first two queries, we'll end up having union of their results in Users collection. Executing the third one will give us all orders in Orders collection, but only subset of those will be contained in Navigation collections of User instances on client. It works really well and as Entities get added to Users collection(by query, or by user's action, or by other viewmodel's side effect) those get displayed on UI right away through binding to ObservableCollection wrapper over Users EntitySet.
The same gets reflected on canceling changes, and I don't need to do a lot for that - just providing observable interface.
With BreezeJS and JS particularly, it looks like that I should be subscribing to various events of Breeze and synchronize data with my Kendo UI observable array instance (which is in fact copying data between breeze cache and Kendo UI observable array).
In WCF Ria Services, Context.Users entityset has EntityAdded / EntityDeleted events which makes it possible to handle additions/removals in our ViewModels.
The same events are also available for NavigationCollections, so we might do user.Orders.EntityAdded += ... for example.
So, I'm trying to implement something similar to what we had in WCF Ria Services + Silverlight using Angular + BreezeJS + Kendo UI in TypeScript. I have kind of found analogs for EntityAdded/Deleted events for EntitySet in Breeze but didn't find anything like this for NavigationCollections.
Could someone let me know if the path I'm trying to go with is completely awkward in BreezeJS/KendoUI/Angular world? If no, how do I handle changes in navigation collections in BreezeJS?
I'm using Ninject Event Broker extensions and I have two services. ServiceOne is the Publisher of an event. ServiceTwo is the subscriber. ServiceOne doesn't have a hard dependency to ServiceTwo, I'm creating the dependency using the DependencyCreation extension.
Here are the requirements:
I want to define a one-to-one event between these two objects. Only the ServiceTwo instance created by DependencyCreation should receive the event.
If there are other instances of ServiceTwo further down in the object
graph they shouldn't receive the event. (this shouldn't be the case
but I want to account for it)
ServiceTwo should be disposed of when ServiceOne is disposed.
This is a web application and the life of ServiceOne should only be
for one request.
Basically I'm just trying to recreate the behaviour of me writing:
var publisher = new Publisher();
var subscriber = new Subscriber();
var subscriber2 = new Subscriber();
publisher.MyEvent += subscriber.MyEventHandler;
One publisher. One subscriber. Subscriber2 doesn't get the event.
Here's my code:
this.Bind<IServiceOne, ServiceOne>().To<ServiceOne>().Named("ServiceOne").OwnsEventBroker("ServiceOne").RegisterOnEventBroker("ServiceOne");
this.Kernel.DefineDependency<IServiceOne, IServiceTwo>();
this.Bind<IServiceTwo>().To<ServiceTwo>().WhenParentNamed("ServiceOne").InDependencyCreatorScope().RegisterOnEventBroker("ServiceOne");
Two questions.
Does this fulfill my requirements?
Is there a better way?
I don't normally like to answer my own question but seeing as this has been quiet for a while, I've been testing my code sample and it appears to work fine. To clean up the creation of these dependencies and the whole event broker registration process I created some extension methods. First off an IsPublisher extension that creates a scoped event broker:
public static ISubscriberBuildingSyntax IsPublisher<TPublisher>(this IBindingWhenInNamedWithOrOnSyntax<TPublisher> syntax)
{
string name = Guid.NewGuid().ToString();
syntax.Named(name);
syntax.OwnsEventBroker(name).RegisterOnEventBroker(name);
return new SubscriberBuildingSyntax<TPublisher>(syntax, name);
}
Secondly, a generic CreateSubscriberDependency method that creates a dependency using Dependency Creator:
public ISubscriberBuildingSyntax CreateSubscriberDependency<TSubscriber>() where TSubscriber : class
{
this.syntax.Kernel.DefineDependency<TPublisher, TSubscriber>();
this.syntax.Kernel.Bind<TSubscriber>().ToSelf().WhenParentNamed(this.name).InDependencyCreatorScope().RegisterOnEventBroker(this.name);
return this;
}
I can then call this like so:
this.Bind<IRegistrationService>().To<RegistrationService>()
.IsPublisher()
.CreateSubscriberDependency<RoleService>();
This creates an Event Broker scoped to the RegistrationService instance with a RoleService dependency that is tied to the life of RegistrationService.
I can then register RegistrationService with InRequestScope to limit this to the life of one request.
I have a WCF Service, hosted inside of IIS, using NHibernate for data access.
In my Global.asax I configure NHibernate on Application_Start. This means that I only perform the expensive task of setting up all of the mappings once for my WCF Service.
The only problem with this is that if the database was unavailable during start up, the mappings will never get set up (as they will have failed to be set up during Application_Start and the event won't be called again until the app pool is recycled).
How can I handle the NHibernate set up so it occurs only once, except where there is an error (such as the database not being available) in which case it will occur on each request until it works?
What you need is a Lazy Singleton to be your SessionFactory. You call a method to get the session factory and it checks if the session already exists. So the expensive task of creating the Session Factory is done the first time someone needs it.
You could do something like this:
public ISessionFactory GetSessionFactory()
{
// sessionFactory is STATIC
if (sessionFactory == null)
{
global::NHibernate.Cfg.Configuration cfg = new NHibernateConfigurationFactory(CurrentConfiguration).GetConfiguration(sessionFactoryName);
// Now that we have our Configuration object, create a new SessionFactory
sessionFactory = cfg.BuildSessionFactory();
if (sessionFactory == null)
{
throw new InvalidOperationException("cfg.BuildSessionFactory() returned null.");
}
}
return sessionFactory;
}
A complete solution is available here:
NHibernate - good complete working Helper class for managing SessionFactory/Session
I am throwing this answer into the mix in order to get comments on it - this answer was emailed to me, but I'd appreciate the view of the SO community before I decide on the final solution...
Rather than using the Application_Start event, use the Begin_Request event. Store the NHibernate session in a field and in the Begin_Request event, check if the field is null and if it is, create the NHibernate session (otherwise, continue to use the one already created).
So essentially, this would mean moving the create logic into a method I can call from Begin_Request in the event of "detecting that the session hasn't yet been created".
If i have the following Repository:
public IQueryable<User> Users()
{
var db = new SqlDataContext();
return db.Users;
}
I understand that the connection is opened only when the query is fired:
public class ServiceLayer
{
public IRepository repo;
public ServiceLayer(IRepository injectedRepo)
{
this.repo = injectedRepo;
}
public List<User> GetUsers()
{
return repo.Users().ToList(); // connection opened, query fired, connection closed. (or is it??)
}
}
If this is the case, do i still need to make my Repository implement IDisposable?
The Visual Studio Code Metrics certainly think i should.
I'm using IQueryable because i give control of the queries to my service layer (filters, paging, etc), so please no architectural discussions over the fact that im using it.
BTW - SqlDataContext is my custom class which extends Entity Framework's ObjectContext class (so i can have POCO parties).
So the question - do i really HAVE to implement IDisposable?
If so, i have no idea how this is possible, as each method shares the same repository instance.
EDIT
I'm using Depedency Injection (StructureMap) to inject the concrete repository into the service layer. This pattern is followed down the app stack - i'm using ASP.NET MVC and the concrete service is injected into the Controllers.
In other words:
User requests URL
Controller instance is created, which receives a new ServiceLayer instance, which is created with a new Repository instance.
Controller calls methods on service (all calls use same Repository instance)
Once request is served, controller is gone.
I am using Hybrid mode to inject dependencies into my controllers, which according to the StructureMap documentation cause the instances to be stored in the HttpContext.Current.Items.
So, i can't do this:
using (var repo = new Repository())
{
return repo.Users().ToList();
}
As this defeats the whole point of DI.
A common approach used with nhibernate is to create your session (ObjectContext) in begin_request (or some other similar lifecycle event) and then dispose it in end_request. You can put that code in an HttpModule.
You would need to change your Repository so that it has the ObjectContext injected. Your Repository should get out of the business of managing the ObjectContext lifecycle.
I would say you definitely should. Unless Entity Framework handles connections very differently than LinqToSql (which is what I've been using), you should implement IDisposable whenever you are working with connections. It might be true that the connection automatically closes after your transaction successfully completes. But what happens if it doesn't complete successfully? Implementing IDisposable is a good safeguard for making sure you don't have any connections left open after your done with them. A simpler reason is that it's a best practice to implement IDisposable.
Implementation could be as simple as putting this in your repository class:
public void Dispose()
{
SqlDataContext.Dispose();
}
Then, whenever you do anything with your repository (e.g., with your service layer), you just need to wrap everything in a using clause. You could do several "CRUD" operations within a single using clause, too, so you only dispose when you're all done.
Update
In my service layer (which I designed to work with LinqToSql, but hopefully this would apply to your situation), I do new up a new repository each time. To allow for testability, I have the dependency injector pass in a repository provider (instead of a repository instance). Each time I need a new repository, I wrap the call in a using statement, like this.
using (var repository = GetNewRepository())
{
...
}
public Repository<TDataContext, TEntity> GetNewRepository()
{
return _repositoryProvider.GetNew<TDataContext, TEntity>();
}
If you do it this way, you can mock everything (so you can test your service layer in isolation), yet still make sure you are disposing of your connections properly.
If you really need to do multiple operations with a single repository, you can put something like this in your base service class:
public void ExecuteAndSave(Action<Repository<TDataContext, TEntity>> action)
{
using (var repository = GetNewRepository())
{
action(repository);
repository.Save();
}
}
action can be a series of CRUD actions or a complex query, but you know if you call ExecuteAndSave(), when it's all done, you're repository will be disposed properly.
EDIT - Advice Received From Ayende Rahien
Got an email reply from Ayende Rahien (of Rhino Mocks, Raven, Hibernating Rhinos fame).
This is what he said:
You problem is that you initialize
your context like this:
_genericSqlServerContext = new GenericSqlServerContext(new
EntityConnection("name=EFProfDemoEntities"));
That means that the context doesn't
own the entity connection, which means
that it doesn't dispose it. In
general, it is vastly preferable to
have the context create the
connection. You can do that by using:
_genericSqlServerContext = new GenericSqlServerContext("name=EFProfDemoEntities");
Which definetely makes sense - however i would have thought that Disposing of a SqlServerContext would also dispose of the underlying connection, guess i was wrong.
Anyway, that is the solution - now everything is getting disposed of properly.
So i no longer need to do using on the repository:
public ICollection<T> FindAll<T>(Expression<Func<T, bool>> predicate, int maxRows) where T : Foo
{
// dont need this anymore
//using (var cr = ObjectFactory.GetInstance<IContentRepository>())
return _fooRepository.Find().OfType<T>().Where(predicate).Take(maxRows).ToList();
And in my base repository, i implement IDisposable and simply do this:
Context.Dispose(); // Context is an instance of my custom sql context.
Hope that helps others out.
I am trying to implement an observer pattern using ninject and NHibernate.
I'd like to be able to inject observers that act as "triggers" when an object is persisted or deleted via NHibernate.
Key points-
I want the observer to be notified any time an object is persisted, including cascaded saves, which is why I am using NHibernate PostInsert/PostUpdate events.
I want to be able to inject the observers via Ninject (don't want the kernel anywhere in the nhibernate event handlers).
The observers are different depending on the type of the object being persisted, so I need a good way to know which observers should be called in the NHibernate events.
My code works great now for objects that are loaded via NHibernate using constructor injection. An observer class is injected into the domain model, which is carried through the nhibernate events and can be fired off no problem.
The problem: Our existing codebase uses default constructors for our domain objects versus a factory. Because of this, the observers will not be injected unless we switch to using a factory.
I know that switching everything to a factory will work, but I wanted to see if anyone has any better suggestions for accomplishing this. So, should I make a factory to instantiate new objects or something else?
It looks like you are making life complicated for yourself by trying to put Observer pattern on top of NHibernate's Event Handler pattern.
NHibernate already provides a way of having pluggable event listeners - why not just make use of that?
class FooPostInsertEventListener : IPostInsertEventListener
{
public void OnPostInsert(PostInsertEvent #event)
{
var entity = #event.Entity;
var entityType = entity.GetType();
if (entityType != typeof(Foo)) return;
ProcessFoo(entity);
}
}
If you are desperate to go through the Kernel, then you can even use the Kernel when configuring NHibernate. Something like this:
config.EventListeners.PostInsertEventListeners = Kernel.GetAll<IPostInsertEventListener>().ToArray();