How can I programmatically create a transactional proxy? - java

I created a bean instance with
Type instance = new Type();
and autowired it using
ctx.getAutowireCapableBeanFactory().autowireBean(instance);
The beans run method is executed by a ThreadPoolTaskExecuter and is annotated with the
#Transactional annotation which has no effect in this case. Since lazy loading problems occur. I need a transaction here.
How can I create a transactional proxy and wrap my instance?
Is there a way other than using transaction-manager manually?

You should get the correct proxy if you apply BeanPostProcessors from the context:
instance = ctx.getAutowireCapableBeanFactory().applyBeanPostProcessorsAfterInitialization(instance);

You can certainly create a PlatformTransactionManager subclass manually and use its methods to create and commit or rollback transactions.
If you want to proxy an object, the class you probably want is org.springframework.transaction.interceptor.TransactionProxyFactoryBean. Setup an instance of that and call getObject() to get your proxied class.

Related

Spring Boot: Calling a #Bean method several times

Suppose we have a method for creating some bean
#Bean MongoClient getMongo() {}
Occasionally, I see in examples people calling several times to the method itself when they want to use the bean (in our example getMongo())
Does Spring Boot somehow enable the creation of the bean only once or is it being created with every call to the method?
Actually each time you get the same object. As it was said, the default scope for spring beans is singleton which means there is only one instance of your class in Spring container.
Why do you receive the same object each time?
It's because #Configuration annotation that you used in your class implicates creation of proxy (which is subclass of your class annotated with #Configuration). This proxy stores singleton and returns reference to it whenever you call #Bean method.
Why #Bean method returns reference instead of creating object as it is in implementation?
Proxy also overrides your #Bean method.

Lazy loading working in non-transactional class/method in Hibernate

I am working in Spring-Hibernate application. Flow is as usual: Controller --> Service --> DAO.
I have annotated Service layer class with #Transactional, thereby marking every method transactional in that class.In service class, I made a DAO call to get some domain object and then converting it into DTO/VO object which will be passed to controller.For converting domain object to DTO, I have written another custom static class(class having only static methods) like ObjectMapper which will do this conversion.
Now, domain object has some child object(One to Many) which is lazily loaded. So, when in ObjectMapper, i access that child getter method, an extra database call is issued, which is working fine.
What I don't understand is that since ObjectMapper is not transactional, I was expecting some exception to be thrown like Session is closed while making database call to fetch child object from database.I am using getCurrentSession of Session Factory in DAO.
Can someone please explain me this behavior?
I suppose you either call your ObjectMapper from the transactional Service method (you should) or if not, maybe you are enabled "hibernate.enable_lazy_load_no_trans" which keeps the hibernate session open
As long as the call to the static class/method, which transforms your objects, is made in the transactional method of the DAO, the session is still open and will be used for the database calls.

Some doubts about lazily instantiation in Spring? How it works?

I am studying for the Spring Core certification and I have some doubts related this questions:
In Spring are beans lazily or eagerly instantiated by default? How do
you alter this behavior?
So I know that the bean are eagerly instantiated by default by the Spring Container and I know that it automatically create my beans (declared into the configuration) in right order with its dependencies injected. And I know that after dependency injection each bean goes through a post-processing phase in which Further configuration and initialization may occur. So at the ending of this phase my beans are fully initialized and ready for use.
So I think that the meaning of eagerly beans instantiation is the behavior of the creation of the declared bean before the application start. Is it right or am I missing something?
At the contrary the lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed.
And so I have my first doubt about it. Is this the same behavior of a classi Java application (that don't use Spring) in which, at a certain point of the program execution, I declare a statment like this:
private void myMethod() {
....................................
....................................
....................................
DO SOMETHING
...................................
MyObject myObject = new MyObject(); // Is it lazily instantiated?
....................................
....................................
}
So in the case of the previous snippet is it the MyObject myObject lazily instantiated (this is not instantiated before that my application start but it is instantiated at certain pint of the application execution) or am I missing something?
By the way coming back at the original question: How can I alter the default behavior and how can I instantiate a bean in a lazily way?
Reading on the course documentation I found that Spring support Lazy beans ant it say this assertion:
Lazy beans are supported – only created when getBean() called. Not
recommended, often misused: #Lazy or <bean lazy-init=“true” ...>
So I thing to understand that (by I am not sure about it) that if into my Java code I do something like:
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Hello hello = (Hello) appContext.getBean("hello");
the bean having id hello is lazily instantiated. Is it true or is it wrong or missing something?
If it is true from what I can understand reading the previous documentation it is not a good idea use the previous solution (why?) but it is better to choose annotate the bean configuration (into the Java configuration class) that have to be lazily instantiated with the #Lazy annotation or use <bean lazy-init=“true” ...> into the XML configuration (of the bean).
So it means that #Lazy in Spring can be used inside #Configuration classes. The bean which has been declared with #Lazy annotation will not be initialized by spring container. #Lazy will be initialized by container only when that bean will be accessed somewhere in code.
Ok, but now my doubt is: how can I access to a bean that is not yet instantiated? Can you show me an example of it?

Create Beans in Spring dynamiclly

I am using Spring3.1
My application will have kind of bean-manager.
That manager will be able to retrieve request and on each request I need to create new instance of bean dynamically which will be initiate with it's own unique params.
The params will be retrieved via the request method.
This bean must be alive and work asynchronously. (For example it will listen to jms calls, execute methods by demand and so on..)
Moreover I want to have the option to destroy beans also.
Those bean could be resemble as sessions so when the user log off i will destroy those beans.
I understand that I have to create some kind of bean-list or beans pool and manage it with some kind of manager.
How can I create those beans dynamically and have them remain them alive until I destroy them?
Any idea how could I implement such thing?
Well in this sense, the easiest way would be to create a StaticApplicationContext setting its parent context as the common context (the one holding the beans you want to share over all). This you could reach by doing something like:
StaticApplicationContext innerContext = new StaticApplicationContext(parentContext);
after this, you probably want to declare the bean you want to instantiate over Spring in order to attach all the AOP stuff, Autowiring and other functionalities, therefore you will need to do something like:
innerContext.registerSingleton("beanName", beanClass);
After registering you could instantiate the bean like:
innerContext.getBean(beanClass);
Of course there is the implementation of scope Session for spring and therefore I advise you to check the WebApplicationContext documentation, method loadParentContext that you basically pass the ServletContext as paramenter.
I've also found many trouble in creating a bean dynamically at run-time and used it anywhere in application..
Here is complete code
static ApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] { "Spring-Question.xml" });
static StaticApplicationContext innerContext = new StaticApplicationContext(appContext);
Create the bean and set the values e.g.
innerContext.registerSingleton("beanName", Test.class);
Test test = innerContext.getBean(Test.class);
test.setA(3);
test.setB(4);
Then Re-Use the bean anywhere in application....
Test test = innerContext.getBean(Test.class);
System.out.println(test.setB(4));

Is it okay to pass injected EntityManagers to EJB bean's helper classes and use it?

We have some JavaEE5 stateless EJB bean that passes the injected EntityManager to its helpers.
Is this safe? It has worked well until now, but I found out some Oracle document that states its implementation of EntityManager is thread-safe. Now I wonder whether the reason we did not have issues until now, was only because the implementation we were using happened to be thread-safe (we use Oracle).
#Stateless
class SomeBean {
#PersistenceContext
private EntityManager em;
private SomeHelper helper;
#PostConstruct
public void init(){
helper = new SomeHelper(em);
}
#Override
public void business(){
helper.doSomethingWithEm();
}
}
Actually it makes sense.. If EntityManager is thread-unsafe, a container would have to do
inercept business()
this.em = newEntityManager();
business();
which will not propagate to its helper classes.
If so, what is the best practice in this kind of a situation? Passing EntityManagerFactory instead of EntityManager?
EDIT: This question is very interesting so if you are interested in this question, you probably want to check out this one, too:
EDIT: More info.
ejb3.0 spec
4.7.11 Non-reentrant Instances
The container must ensure that only one
thread can be executing an instance at
any time. If a client request arrives
for an instance while the instance is
executing another request, the
container may throw the
javax.ejb.ConcurrentAccessException to
the second client[24]. If the EJB 2.1
client view is used, the container may
throw the java.rmi.RemoteException to
the second request if the client is a
remote client, or the
javax.ejb.EJBException if the client
is a local client.[25] Note that a
session object is intended to support
only a single client. Therefore, it
would be an application error if two
clients attempted to invoke the same
session object. One implication of
this rule is that an application
cannot make loopback calls to a
session bean instance.
And,
4.3.2 Dependency Injection
A session bean may use dependency injection
mechanisms to acquire references to
resources or other objects in its
environment (see Chapter 16,
“Enterprise Bean Environment”). If a
session bean makes use of dependency
injection, the container injects these
references after the bean instance is
created, and before any business
methods are invoked on the bean
instance. If a dependency on the
SessionContext is declared, or if the
bean class implements the optional
SessionBean interface (see Section
4.3.5), the SessionContext is also injected at this time. If dependency
injection fails, the bean instance is
discarded. Under the EJB 3.0 API, the
bean class may acquire the
SessionContext interface through
dependency injection without having to
implement the SessionBean interface.
In this case, the Resource annotation
(or resource-env-ref deployment
descriptor element) is used to denote
the bean’s dependency on the
SessionContext. See Chapter 16,
“Enterprise Bean Environment”.
I used a similar pattern, but the helper was created in #PostConstruct and the injected entity manager was passed in the constructor as parameter. Each EJB instance had its own helper and thread-safety was guaranteed then.
I also had a variant were the entity manager was not injected (because the EJB wasn't using it altogether), so the helper has to look it up with InitialContext. In this case, the Persistence context must still be "imported" in the parent EJB with #PersistenceContext:
#Stateless
#PersistenceContext(name="OrderEM")
public class MySessionBean implements MyInterface {
#Resource SessionContext ctx;
public void doSomething() {
EntityManager em = (EntityManager)ctx.lookup("OrderEM");
...
}
}
But it's actually easier to inject it (even if the EJB doesn't use it) than to look it up, especially for testability.
But to come back to your main question, I think that the entity manager that is injected or looked up is a wrapper that forwards to the underlying active entity manager that is bound to the transaction.
Hope it helps.
EDIT
The section § 3.3 and § 5.6 in the spec cover a bit the topic.
I've been using helper methods and passed the EntityManager there, and it is perfectly OK.
So I'd recommend either passing it to methods whenever needed, or make the helper a bean itself, inject it (using #EJB) and inject the EntityManager there as well.
Well, personally, I wouldn't like to have to pass the Entity Manager to all my POJOs in my constructors or methods. Especially for non-trivial programs where the number of POJOs is large.
I would try to create POJOs/HelperClasses that deal with the Entities returned by the EntityManager, instead of using the entitymanager directly.
If not possible, I guess I'd create a New EJB Bean.

Categories