Using stateless EJB beans in an Entity Bean - java

Obviously using stateless EJB beans in an entity bean smells, but please consider a scenario as follows and tell me if you know of a better solution:
I have an InvoiceTemplate Entity Bean with field NextInvoiceDate
Generating NextInvoiceDate is a complex procedure and should be performed outside of the InvoiceTemplate class
NextInvoiceDate should be updated each time InvoiceTemplate is stored to the db
For now I have logic regarding the generation of NextInvoiceDate in #PrePersist #PreUpdate methon in InvoiceTemplate entity bean. The logic is getting more and more complicated and I want to move it outside of the InvoiceTemplate entity bean. It looks to me that there should be a service to calculate NextInvoiceDate. But then is it right to invoke this service from the inside of InvoiceTemplate?

It isn't such a smell - it is a lean towards domain-driven design.
I don't know of any way to do this automatically, but you can:
in the session beans where you handle your Invoicetemplate, inject the helper bean that has the logic to calculate the next date
create a private field with a setter on the entity, and before you start using it call entity.setNextDateHelper(..)
You can also check whether AspectJ doesn't offer some EJB options so that you can inject the EJB whenever an entity of a given type (InvoiceTemplate) is created. AspectJ works like that with spring beans, I don't know whether there are such options for EJB.

Do you need anything as complicated as a service or EJB? Can you just write a static method (possibly on a utility class) to hold the logic? Normally I'm pretty biased against this sort of thing, but if all you've got is some complex logic that doesn't require any DB interaction or a lot of object collaboration, it may be the cleanest approach.

Related

Using a Factory to create JPA entities

I am Thinking of creating A JPA 2.0 Mapping of an entity, however I do not want to have any setters or expose a constructor, I want to use a Factory to create my class whenever it is fetched from the db.
I have taken a look at the pro JPA 2.0 book and some articles online, but cannot find anything similar, has anyone done anything like this?
Thank you,
Use field access and add a private constructor. JPA can access private fields.
Factory pattern actually is a good candidate for JPA Entities. However it is practically impossible to make entity manager use your custom factory on fetching unless you make your own JPA implementation.
But there are still many applications of factory, especially for CRUD programms. The most important IMHO is context depending defaults for fields, concerning user created new entities of course.
For full stack java-ee applications I prefer to use Singleton EJB for this purpose, as it has easy access to JPA Entity manager.
You can make protected constructor for entity to prevent user instantiation.

JTA & MySQL - How to Retrieve records from database

I am new to JTA and I need a method to retrieve some some elements from the database. I can do this through EntityManager but that works only for ResourceLocal.
I want to know how can I do this:
Query q = em.createNamedQuery("AnyQuery");
q.getResultList();
without the use of EntityManager.
Any ideas?
The question itself shows that you don't understand any of the technologies you try to work with. You probably need to study some more general stuff before you do any actual development.
you are probably confusing JTA and JPA,
your statement about RESOURCE_LOCAL is not true (and irrelevant) - there are JTA and RESOURCE_LOCAL transactions and in Java EE you usually use the former,
your thought of using Named JPA queries without EntityManager is plain absurd and probably stems from misunderstanding of some kind (what would be the point of using named queries without an entity manager?),
saying "some elements from database" shows that you can't really tell the difference between records and mapped objects, in which case you probably should not use JPA at all.
I am not really expecting that you accept this answer. That's just my frustration taking over.
EDIT
OK, now that you mentioned JSF I understand more of your problem.
I assume you want to use JPA. In such case you have a choice of:
creating your own EntityManager (in such case you cannot have it injected; instead you have yo use an EntityManagerFactory and build your own). This is an "application managed EntityManager". You don't really want to do this.
using an injected EntityManaged ("conatiner managed EntityManager"). This is the standard choice.
Now you need a transaction. Since you should be using a JTA EntityManager, you will need a transaction object that is responsible for coordinating the whole thing. Again, you have two choices:
in a JSF bean, inject a UserTransaction (using #Resource annotation). This is messy, error-prone and takes a lot of boilerplate, but you will find all the necessary methods. You can create your own (application managed) EntityManager, call its joinTransaction method and then call begin-commit on UserTransaction. This is would be an "application managed transaction"
move your EntityManager code to EJB. It only takes a couple of lines of code and a single annotation (#Statless). All the code inside an EJB is - magically - wrapped inside a transaction that the container manages for you. This is the "container managed transaction" - the default and common choice.
Each of the things above could (and should) be expanded with some additional information. But the short path for you is:
create an EJB (a simple class with #Stateless annotation),
move the method that uses EntityManager to the EJB,
inject the EJB into your managed bean (using #EJB annotation) and call the relevant method.
The JTA transaction will happen around each call to any EJB method. This should get you started :-)

Can I get a reference from a JPA bean to the EntityManager instance that manages it?

The question basically sums it up.
Play framework has the JPABase class that JPA beans inherit from. This class has a method called em() which returns the bean's entityManager instance. Is there something equivalent to this in plain JPA?
AFAIK, no. And I would find it very questionable. JPA entities are supposed to be POJOs usable outside of the persistence layer, where the JPA classes are not even in the classpath. Exposing the EntityManager in those POJOs seems wrong to me.
It looks like the Play Framework implements the Active Record pattern allowing you to make persistence operations directly in the bean. This is perfectly acceptable and you can implement a similar solution.
However, once you choose this approach, you will not have the benefits of POJOs. For example, this solution may not be the best alternative if your application has n-tier architecture.
Anyway take a look at the source code, it's free!
https://github.com/playframework/play/blob/master/framework/src/play/db/jpa/JPABase.java

Why isn't guice injecting the previously-instantiated #SessionScoped object?

I have a #SessionScoped? DAO that's being injected into a Stripes framework Interceptor constructor that seems to be found from the interceptor (on subsequent calls) but is not being injected into a service in the same request (and session). Why isn't the same instance (initialized in the interceptor) being reused in the service (which is in a different package in the same project)?
Making the DAO a #Singleton does the trick, but is unacceptable as the DAO stores information that must remain consistent throughout a user's session on an application that has multiple users who would be sharing the same DAO instance.
If the Interceptor is not a session-scoped object, then you'll need to inject Provider<YourDaoType> into the Interceptor. This is the common pattern to use when an object with a long life depends on another object with a shorter life.
ok, I've figured it out. I changed the #SessionScoped to a bind(DAO.class).in(ServletScopes.SESSION) statement with which the injection works. As far as I understand, these should be equivalent, but in my case they're producing different results.
One aspect that was troubling me along the way was that Stripes built the interceptor that injected the DAO on startup causing errors as this happened outside the scope of a session (which the DAO is #SessionScoped. ActionBeanContext context information is needed to initialize the DAO session context which I set in an AbstractActionBean setContext method that is called during the construction of the action bean.
Thanks for your interest and help.

How to design DAOs when the datasource varies dynamically

Usually when defining a DAO, you would have a setter for the datasource on the DAO object.
My problem is that our datasource varies dynamically based on the request to the server. i.e. every request can access different database instance.
The request holds logical properties, that later can be used to retrieve the connection to the DB of the request.
So when dependency injecting the DAO to the business logic object, I need a way to set the properties on the DAO at runtime (not configuration time).
One solution is to store the datasource on the thread local, but I don't really like messing with thread local variables.
Another option is to have an initialize method on the business logic object that calls initialize on the DAO with the request properties.
I guess it's a common problem, can you suggest a common solution?
Your problem is a little confusing. Having one DAO access multiple different datasources would seem to be a maintenance nightmare. As a result, you should define one DAO interface containing all the methods you would want to call. For each database you are connecting to I would construct a new class that implements your DAO interface. This allows you to have multiple implementations. I would then store these implementations (each that has its own datasource) in a Map (java.util.Map), using your "logical properties" as the key to the map. Since all your DAO Implementations implement your interface you will be able to cast them to the interface and use them interchangeably. On your business object, you would inject the Map of DAO implementations. I hope this helps your design.
I had such a problem on a client/server project. Client and Server projects was sharing Dao interfaces. And When I used to do database operation I had to select suitable Dao implementation. My solution was like this :
IVehicleDao vehicleDao =daoFactory.Get<IVehicleDao>(parameters);
vehicleDao.doSomething();
Get dao from Factory by passing parameters.Inside Dao factory decide which Dao implementation to return..
You may want to look into this class:
http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.html
This will make it easier for your service objects and data access objects to be ignorant that any notion of dynamic datasources exists.
Typically you'd need to implement a servlet filter and use a ThreadLocal so that the DataSourceLookup implementation used by AbstractRoutingDataSource can easily gain access to the request parameters that dictate which DataSource is returned. If you really want to avoid that, you could implement a servlet filter which sets properties on a request-scoped bean and inject that bean into the DataSourceLookup implementation you've written. Request-scoped beans still use a ThreadLocal in their implementation but at least this way it's Spring's impl, not yours, and you don't need to worry about it. :)
Similar approach is detailed in this blog entry from the Spring team:
http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/
It sounds like your problem is that you are creating a single DAO instance for your application. You either need to create a separate instance for each datasource (maybe making some kind of dao controller to manage it all for you) or possibly allow your methods in your dao to be static and pass all information about how to connect to the datasource along with the data you are persisting into every method.
I already did this. You need to create one DAO each class, and in the scope of your DAO you need to pass the DATASOURCE and finally one class CONTROLLER where you do dynamic calling to DAO.

Categories