ejb references passed in helper class or create ejb instead - ejb-3.0

I was wondering which one of the two solutions hereunder is the best practice?
Problem : I have a stateless session bean VehicleBean, I implemented a method with business logic and persistence of a Car with its wheels , their tires, etc.
#Stateless
class VehicleBean{
#PersistenceContext
private EntityManager em;
#EJB
Inspector inspectorBean;
#EJB
DocumentBean documentBean;
public void persistCar(){
Car car = new Car();
car.setMake("Ford");
em.persist(car);
documentBean.persistDocument(new Document(car));
for (int i = 0; i < 4; i++){
createWheel(car);
}
private void createWheel(Car car){
// some business logic
inspectorBean.inspect();
Wheel wheel = new Wheel();
wheel.setCar(car);
em.persist(wheel);
...
}
...
}
I have different private methods that are called after each other (1) create car, 2) create wheels, etc) and I would like to regroup all these methods in one helper class.
Solutions:
1) Make use of a helper class CarBuilder which contains all the private methods from my VehicleBean. As I can't use ejb injection, I want to pass it by reference to the constructor as following :
public void persistCar(){
new CarBuilder(this, document, inspectorBean);
}
class CarBuilder{
private VehiculeBean vehiculeBean;
...
CarBuilder(VehiculeBean,....){
this.vehiculeBean = vehiculeBean;
}
}
2) create CarBuilder as a stateless session bean and inject the bean in the VehiculeBean.
Do you see any advantage using the 2)? So having a lot of different beans like CarBuilder, MotorcyleBuilder, etc managed by the container.

Passing references to container managed objects in constructors will decrease readability of the code (IMO). Code becomes a lot clearer if you create container managed resources with dependency injection.
Let the helper classes work with the entities instead and create a new EJB when you want to break out bussiness logic in another class.

Related

Spring Singleton and concurrent access

My question is :
let's assume that i have a spring bean : a DAO one (it's a singleton of course)
So, when we have lot of users who want to use this bean at the same time : what happens?
or,
for every user, spring instantiate a DAO bean for him?
==> we have a singleton by application Context : did spring create a context for every user?
(it's a singleton of course)
Then it's a singleton. The ApplicationContext will only create one instance and pass that same instance around wherever it's requested.
for every user, spring [instantiate] a DAO bean for him?
No, it will retrieve and give them the same DAO instance.
==> we have a singleton by application Context : did spring create a context for every user?
I'm not exactly sure what you mean for every user. A Java application has no knowledge of users. If you mean in the context of a multithreaded application, it's still irrelevant. The injected DAO bean will still be that single instance.
As stated in the comments, it's your responsibility to handle the state of your DAO, if it's mutable, handle concurrent access. Handle transactions (possibly with #Transactional) with the datasource.
You dont use DAOs as Spring beans. Spring beans (singleton scope) are more like a service.
Lets say you have a Pizza Dao, and a PizzaService, your Service is a spring bean, while pizza isnt.
class Pizza {
Set ingredients = ... ;
public Pizza(Set s) {
...
}
private addIngredient(Object o ) {
set.add...
}
}
#Service
class PizzaService {
private Pizza createPizza(..){
Pizza p = new Pizza();
....
return pizza;
}
private void persistPizza(Pizza pizza){
..save to db..
}
}
Test your service:
class JunitFoo{
#Autowired private PizzaService service;
#Test
someMethod(){
Pizza p = service.createPizza();
p.addIngredient(cheese)
service.persistPizza(p);
}
}
You can also implement Runnable in JunitFoo and launch someMethod a lot of time with differents threads (your User), every user will get its own Pizza. But all users use the same pizzaService.
Due to this reason singleton is default scope of a spring bean. You can also create a Pizza by fetching it from your application context, but in this case, you would need prototype otherwise all users share the same pizza
<bean id="pizza" class="foo.Pizza" scope="prototype" >
<default set of pizza stuff>
</bean>
If you do it that way, your PizzaService could look like this:
#Service
class PizzaService {
#Autowired private ApplicationContext context;
private Pizza createPizza(..){
return (Pizza) context.getBean("pizza");
}
private void persistPizza(Pizza pizza){
..save to db..
}
}
This topic is way to big to cover it in a single post, i hope i could help and improve your understanding. Please also check the spring documantation about bean scopes.

Using Singleton enum in Spring MVC

Here is my singlton class using enum:
public enum MyInstanceFactory {
INSTANCE;
private SOMEOBJECT;
private int countInitialization = 0;
private MyInstanceFactory(){
countInitialization++;
System.out.println("WOW!! This has been initialized: ["+countInitialization+"] times");
SOMEOBJECT = SOMETHING
}
public Session getSomeobject(){ return SOMEOBJECT; }
}
Now I am calling it like inside MVC controller
Session cqlSession = MyInstanceFactory.INSTANCE.getSomeobject();
In this way it calls constructer only first time and next and onwards it return the correct value for SOMEOBJECT.
My question is I want to do the same thing when a spring application start i.e. initializing contructor once and use **getSomeobject** multiple times.
I saw THIS SO ANSWER but here they are saying
If it finds a constructor with the right arguments, regardless of visibility, it will use reflection to set its constructor to be accessible.
Will reflection create problem for a singlton class?
If you need a non-subvertible singleton class (not just a singleton bean that's shared by many other beans, but actually a singleton class where the class can only ever be instantiated once), then the enum approach is a good one. Spring won't try to instantiate the enum itself, because that really makes no sense; that would be a much more extremely broken thing to do than merely calling a private constructor.
In that case, to refer to the enum instance from Spring configuration, you do the same thing as for any other static constant; for example:
<util:constant static-field="MyInstanceFactory.INSTANCE" />

How to inject ISession into Repository correctly?

Please correct me on the following scenario. ( Question is at the end)
(I asked a similar question that was un-organized and it was voted to close. So I have summarized the question here into a scope that can be replied with exact answers.)
I am developing a web application with multiple layers using nhibernate as ORM. My layer structure is as follow
Model Layer
Repository Layer
Services Layer
UI Layer
with the above layers, the classes and interfaces are placed as below.
ProductController.cs (UI Layer)
public class ProductController : Controller
{
ProductServices _ProductServices;
NHibernate.ISession _Session;
public ProductController()
{
_Session = SessionManager.GetCurrentSession();
_ProductServices = new ProductServices(
new ProductRepository(), _Session);
}
// Cont..
}
ProductServices.cs (Service Layer)
public class ProductServices : IProductServices
{
protected IProductRepository _ProductRepository;
protected NHibernate.ISession _Session;
public ProductServices(IProductRepository productRepository,
NHibernate.ISession session)
{
_ProductRepository = productRepository;
_Session = session;
_ProductRepository.SetSession(_Session);
}
// cont...
}
ProductRepository.cs (Repository Layer)
public class ProductRepository : IProductRepository
{
NHibernate.ISession _Session;
public void SetSession(NHibernate.ISession session)
{
_Session = session;
}
public IEnumerable<Product> FindAll()
{
return _Session.CreateCriteria<Product>().List<Product>();
}
//cont..
}
From the UI layer, I create the session as request per session and inject into service layer with the help of class constructor. Then set the session of repository with a help of a method.
I am afraid if I pass the _Session directly to repository as constructor, I will not have the control over it under the service layer. Also there is a future extension plan for using a webservice layer.
** Is there a way to ensure in each method of ProductRepository class that _Session is set already, without writing the piece of code if(_Session==null) in each and every method as it is repeating the same code.
** If the above pattern is wrong, Please show me a right way to achieve this goal.
What you are doing amazed me a bit. You applying the constructor injection pattern in the ProductService, which is definitely the way to go. On the other hand you are not injecting the dependencies into the ProductController, but that class is requesting one of those dependencies through a static class (this is the Service Locator anti-pattern) and creates a ProductServices class itself. This makes this class hard to test and makes your application less flexible and maintainable, since you can't easily change, decorate or intercept the use of the ProductServices class, when it's been used in multiple places.
And although you are (correctly) using constructor injection for the dependencies in the ProductServices, you are passing those dependencies on to the product repository, instead of applying the constructor injection pattern on the ProductResopistory as well.
Please show me a right way to achieve this goal.
The right way is to apply the constructor injection pattern everywhere. When you do this, your code will start to look like this:
public class ProductController : Controller
{
private ProductServices _ProductServices;
public ProductController(ProductServices services)
{
_ProductServices = services;
}
// Cont..
}
public class ProductServices : IProductServices
{
private IProductRepository _ProductRepository;
public ProductServices(
IProductRepository productRepository)
{
_ProductRepository = productRepository;
}
// cont...
}
public class ProductRepository : IProductRepository
{
private ISession _Session;
public ProductRepository (ISession session)
{
_Session = session;
}
public IEnumerable<Product> FindAll()
{
return _Session
.CreateCriteria<Product>().List<Product>();
}
//cont..
}
See how each class only takes in dependencies that it uses itself. So the ProductController and ProductServices don't depend on ISession (I made the assumption that only ProductRepoistory needs ISession). See how -from a class's perspective- everything is much simpler now?
Did we actually solve a problem here? It seems like we just moved the problem of wiring all classes together up the dependency graph. Yes we did move the problem. And this is a good thing. Now each class can be tested in isolation, is easier to follow, and the application as a whole is more maintainable.
Somewhere in the application however, a ProductController must be created. This could look like this:
new ProductController(
new ProductServices(
new ProductRepository(
SessionManager.GetCurrentSession())));
In its normal configuration, ASP.NET MVC will create controller classes for you, and it needs a default constructor to do so. If you want to wire up controllers using constructor injection (which you should definitely do), you need to do something 'special' to get this to work.
ASP.NET MVC allows you to override the default ControllerFactory class. This allows you to decide how to create controller instances. However, when your application starts to grow, it will get really awkward very quickly when you are creating your dependency graphs by hand (as my last example shows). In this case, it would be much better to use a Dependency Injection framework. Most of them contain a feature / package that allows you to integrate it with ASP.NET MVC and automatically allows to use constructor injection on your MVC controllers.
Are we done yet? Well... are we ever? There's one thing in your design that triggered a flag in my brain. Your system contains a class named ProductServices. Although a wild guess, the name Services seems like you wrapped all product related business operations inside that class. Depending on the size of your system, the number of people on your team, and the amount of changes you need to make, this might get problematic. For instance, how to you effectively apply cross-cutting concerns (such as logging, validation, profiling, transaction management, fault tolerance improvements) in such way that to system stays maintainable?
So instead of wrapping all operations in a single ProductServices class, try giving each business transaction / use case its own class and apply the same (generic) interface to all those classes. This description might be a bit vague, but it is a great way to improve the maintainability of small and big systems. You can read more about that here.
You can use a dependency injection container such as Autofac to instantiate your session and manage the lifetime of it. Leave the responsibility of instantiating the session to Autofac and simply inject the ISession interface into any classes that require the dependency. Have a look at this post: Managing NHibernate ISession with Autofac
You will also find this wiki page useful about configuring Autofac with MVC3: http://code.google.com/p/autofac/wiki/MvcIntegration3

How to 'get' the spring prototype beans cleanly?

I would like my other classes to interact with my domain's interfaces rather than implementation, and i would like to avoid hardcoding the implementation in the code, such as this example :
public void addToMyList(String s, int i) {
DomainModel model = new DefaultDomainModelImpl(); // it's hardcoding the implementation here
model.setName(s).setAge(i);
myList.add(model);
}
If i use spring container, with the prototype scope, i can use something like :
// <bean id="myDomainBean" scope="prototype" class="my.package.domain.MyDomainImpl" />
DomainModel myDomainModel = springContext.getBean("myDomainBean");
But i would like to avoid accessing springContext explicitly in my code.
I wonder what's the clean way to do this ?
Im currently thinking of creating a factory implementation for each domain implementation, and autowire the factory to create the beans, but that means different implementations of my domain will have different implementations of the factory also.
Please share your opinions, thank you !
Im currently thinking of creating a factory implementation for each domain implementation, and autowire the factory to create the beans, but that means different implementations of my domain will have different implementations of the factory also.
That is not 100% correct. You can have a factory that take the Interface (class) of the Domain objects that needs to be create. You can inject that factory in you class.
So you will get all the requriements you asked for:
no hard coded new
the domain object code has no dependence to spring
you only have one factory class and one factory method.
example
#Inject
MyStrangeSpringHiddingFactory myStrangeSpringHiddingFactory;
DomainModel myDomainModel = this.myStrangeSpringHiddingFactory.
createInstanceOf(DomainModel.class);
class MyStrangeSpringHiddingFactory implements MyStrangeSpringHiddingFactory {
#Inject
ApplicationContext springContext:
public <T> createInstanceOf(Class<T> clazz) {
return springContext.getBean(clazz);
}
}
This are only my thoughts, because I do not know your use case: Do you really need such in abstraction? Do you really have a domain model where a domain class have several subclasses that need a factory.

How to Produce prototype objects from singleton? (Design help needed)

I'm relatively new to Spring and I've got myself dug in a hole. I'm trying to model motor cars. Each model has it's own builder object, and I have a BuilderFactory that returns the correct builder based upon user selection from a web-app.
So I'm looking for suggestions on how to approach this problem where I need to create a number of individual vehicles, but I don't know what type of vehicle I'm going to need until run-time, and each vehicle needs to be unique to the user.
What I've got at the moment is shown below. The problem I have at the moment is that because the individual builders are singletons so are the individual vehicles. I need them
to be prototypes. I know it all looks pretty horrible so I'm sure there must be a better way of doing this.
The top level from the web-app looks like;
Vehicle vehicle = vehicleBuilderFactory.getBuilder(platform).build();
My vehicleBuilderFactory looks like this;
#Service
public class VehicleBuilderFactory {
#Autowired
Discovery3Builder discovery3Builder;
#Autowired
Discovery4Builder discovery4Builder;
// Lots of #Autowired statements here.
#Autowired
FreeLander2010Builder freeLander2010Builder;
public VehicleBuilder getBuilder(Platform platform) {
switch (platform.getId()) {
case 1: return discovery3Builder;
case 2: return discovery4Builder;
// Lots of case statements here
case 44: return freeLander2010Builder;
default: return null;
}
}
}
which itself looks pretty horrible. Each individual builder looks like;
#Service
public class DefenderBuilder implements VehicleBuilder {
#Autowired
Defender defender;
// Loads of Defender specific setters ommitted
#Override
public Vehicle build() {
return defender;
}
}
and finally the individual vehicle
#Service
#Scope("prototype")
public class Defender extends Vehicle {
}
The main problem now, is that because the builders are singletons, so are the vehicles, and
I need them to be prototypes, because User A's Defender is different to user B's Defender.
You can use Spring's ObjectFactory to have it service up prototype scoped beans from a singleton scoped bean. The usage is pretty straightforward:
#Component
class DefenderBuilder implement VechicleBuilder {
#Autowired
ObjectFactory<Defender> defenderFactory;
Defender build() {
return defenderFactory.getObject()
}
}
#Component
#Scope("prototype")
class Defender {
}
This returns a new Defender on each call to defenderFactory.getObject()
Without reading too much into the detail you say you want to produce Prototype beans from a singleton possibly with a look up in the IoC container.
Section 3.4.6.1 Lookup method injection of the Spring documentation describes how this can be done without losing the Inversion of Control i.e. without your beans knowing about the bean store.
I have made use of the ServiceLocatorFactoryBean to solve a similar problem before. The class level Javadoc is excellent and contains some clear examples.
Two things:
1) You can use proxy in order to hold narrower scope from wider scope(e.g prototype from singleton)
All you need is to define the prototype component with the relevant scope and proxyMode
You can read about scoped proxy here.
2) Another thing that I have noticed is that you plan to use multiple autowired annotation.
note that you can use autowire on a list of interface and it will autowire all components that implements this interface as discussed here.
Moreover you can add a platform id to the VehicleBuilder interface and then generate a map in the constructor e.g:
Map<Integer, VehicleBuilder> vehicleBuilders;
#Autowired
public VehicleBuilderFactory(List<VehicleBuilder> vehicleBuilders) {
this.vehicleBuilders = vehicleBuilders.stream()
.collect(Collectors(x -> x.getPlatformId(), x -> x));
}
in that way you can avoid the switch case.

Resources