Spring autowiring with bean scope of prototype - spring

I have a question in spring with autowire with a bean which is having a scope of prototype..
So basically i am writing a code which is spring with JPA.So i am autowiring my entity manager in my DAO layer .I am loading the entitymanager from a class by using the #configuraion Annotation .
#Configuration
public class DALConfigurationLoader {
#Bean
#Scope("prototype")
public EntityManager getEntityManager() {
}
When i do this i am expecting that for every request it should get a new bean .
#Component
public class OfferPriceDomainDAOImpl {
#Autowired
private EntityManager entityManager;
public OfferPrice getOfferPrice(String offer_Price_Id) throws DataAccessException{
//use entitymanager here
}
}
In this case it is a single entity manager for all the request which is wrong.i want each method should get a new entity manager .As based on the jpa specification every new request should process a new entity manager...How can i autowire a bean with a scope of prototype..
I would really appreciate if some one can answer my question..
Thank,
Swati

Use #PersistenceContext to inject an EntityManager, not #Autowired, as outlined in the JPA section of the Spring reference guide. It takes care of the lifecycle for you properly.
As to why it wasn't working the way you thought it might: whenever an instance of your DAO is created, it would be injected with an EntityManager. Since the EntityManager is scope=prototype, a new one will be created for each DAO that needs to be injected for one. However, since your DAO is a singleton, only one of them is created, so only one EntityManager is ever needed.

#Inject // or #Autowire
Provider<EntityManager> entityManagerProvider;
and then get EntityManager instance using entityManagerProvider.get().
I used javax.inject.Inject instead of Autowire because Provider is defined there too. Also that also would work in Guice.

Related

Whats bean in spring and what is not

lets say I have code like this:
#Repository
public class Foo{
}
#Service
public class Boo{
#Autowired
private Foo foo;
}
so now what here are we calling bean? Bean is the object of Foo type of refrence "foo" BUT are Boo class annotated as Service and Foo as Repository ALSO beans? Ihve been using spring for a while now but this basic question makes me feel bad for not knowing...
In the context of Spring, A bean is a spring managed object. Here spring managed means an object created, initialised, managed, destroyed by Spring IoC container.
Whenever we mark a class with #Component, Spring IOC container will create object for your class and manage it, Whenever we can simply get it from ApplicationContext, or access it using #Autowired/#Resource/#Inject annotations
We can also use #Controller, #Repository, #Service, #ControllerAdvice, #Configuration,#Aspect in place of #Component to tell more specifically that our class is a service or a repository or an aspect etc.
We can also use #Bean annotation to create a bean from method return value
#Configuration
public class SolrConfig {
#Value("${spring.data.solr.host}") String solrUrl;
#Bean
public SolrServer solrServer() {
return new HttpSolrServer(solrUrl);
}
#Bean(name = "solrTemplate")
public SolrTemplate solrTemplate() {
return new SolrTemplate(new HttpSolrServer(solrUrl), RULE_ENGINE_CORE);
}
}
All of your application components (#Component, #Service, #Repository, #Controller etc.) will be automatically registered as Spring Beans
http://docs.spring.io/autorepo/docs/spring-boot/current/reference/html/using-boot-spring-beans-and-dependency-injection.html
Defining Beans can be thought of as replacing the keyword new.
Further information can be found here which might be helpful for understanding Beans in Spring.

Autowire specific implementations of persistence layer in Spring with Java based configuration

In a Spring MVC proyect I'm using Spring Data in the persistence layer so I have a bunch of repositories to access the data. I also have a layer for services so I have things like UserService or AuthorityService that use that repositories.
The problem is that I've been asked to create an interface to be able to change the implementation of the persistence layer (using DAOs for example) without have to touch a single line in the services. How can I specify in an Autowired of that interface what implementation to use? I´m using Java based config and I don't see how to inject it.
I also have a problem with the name of these new interfaces. Normally I would use a name like UserService but Spring use Service for the service layer so, What name is suitable for this type of interface?
You could mark the new implementation of the DAO as #Primary. Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.
#Component
public class FooService {
private FooRepository fooRepository;
#Autowired
public FooService(FooRepository fooRepository) {
this.fooRepository = fooRepository;
}
}
#Component
public class JdbcFooRepository {
public JdbcFooService(DataSource dataSource) {
// ...
}
}
#Primary
#Component
public class HibernateFooRepository {
public HibernateFooService(SessionFactory sessionFactory) {
// ...
}
}
Because HibernateFooRepository is marked with #Primary, it will be injected preferentially over the jdbc-based variant assuming both are present as beans within the same Spring application context, which is often the case when component-scanning is applied liberally.
This annotation is semantically equivalent to the element's primary attribute in Spring XML.
I didn't completely follow your second question.

Spring #Configurable with JavaConfig on GAE-Objectify classes

I have such an Objectify Entity class
#Entity
#Cache
#Index
public class DummyEntity {
#Id private Long id;
private ObjectifyStartup objectifyStartup;
private String someData;
//Getters and setters for all
}
This ObjectifyStartup is a bean initialized in Web MVC JavaConfig file which I need to be injected into any DummyEntity instance
#EnableWebMvc
#Configuration
public class SpringWebMvcConfig extends WebMvcConfigurerAdapter {
#Bean
public ObjectifyStartup objectifyStartup() { return new ObjectifyStartupImpl(); }
}
I want to do this somewhere in the code, basically in a controller
DummyEntity newDummy = new DummyEntity();
I know I need to use #Configurable annotation on the DummyEntity to make the Spring container inject the dependency, but what is the JavaConfig code I have to put into SpringWebMvcConfig class for this DI to work?
I cannot use Autowiring, Component Scans because of the performance hit in GAE due to Autowiring from best practices mentioned here Spring GAE Optimization . And all the solutions I have encountered uses #Autowired with #ComponentScan with <context:spring-configured/>. Kindly provide a solution that uses subjective declarations than autowiring.
After quite some time since I asked this question, I changed the strategy and I am now not initializing a ObjectifyStartup bean to provide me with ofy() service, as from Objectify Docs it is not advisable to create an instance of ofy() and using it pan-application. I was doing it so here because in the ObjectifyStartup bean I was registering all my Entities with the Objectify and then getting hold of its bean instantiation to do datastore operations. But now I have moved the Entities registration to a static block that executes with Spring bootstraps my application.

load data from data base by ajax request by primefaces "selectOnemenu" component

i use spring3 with hibernate3 and jsf2 with primefaces..
I have a problem when i try to load data from the db , i get null pointer Exception as the session factory is null !
I think the problem comes from :
when i made my managedBean in the viewscoped it gives me "Not serializable Exception" so i make all the class members implement serialaizable but it also gives me the not serializable Exception but for this class "org.springframework.orm.hibernate3.LocalSessionFactoryBean" , so i made the session factory transient .
after i made the session factory transient the application works fine but if i made ajax request the session factory is null so i have null pointer exception !!!
any help will be appreciated..
thanks inadvance
Not really create a new session factory
You are using spring so reference tree must be something
ManagedBean -> Spring Service -> Spring Repository
Your managed beans should have reference to a service layer(Singleton). This reference you should mark as transient and fetch from application context in method hooks.
The service bean will always be available from context and you dont have to recreate any instance, its just you pick it back from context.
As for hibernate, it should be in Repository layer and since you have protected your service layer from serialization Repository will not be serialized and hence no issue as above.
#ViewScoped
public class ManagedBean implements Serializable {
#Autowired private transient Service service;
}
#Service
public class ServiceImpl implements Service{
#Autowired private Repository repository;
}
#Repository
public class RepositoryImpl extends HibernateDaoSupport implements Repository {
//here you can have hibernate session factory injected for dao support
}
Hope this helps !!!!!

In Spring, how do I use a ClassPathXmlApplicationContext to get an EntityManager?

With Spring I can autowire a bean with the following property:
#PersistenceContext(unitName="foo") private EntityManager em;
Using the following I can manually autowire the bean "someBean":
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext("META-INF/applicationContext.xml");
AutowireCapableBeanFactory fac = ctx.getAutowireCapableBeanFactory();
fac.autowireBean(someBean);
However, I can't figure out how to directly get a particular EntityManager. The use case is that I want to write a test that will get all EntityManager objects and execute simple queries in them to ensure that they are set up properly. To do this I need to be able to get all EntityManager objects from the application context. How can I do that?
The following does not work. It returns an empty map.
Map<String,EntityManager> ems = ctx.getBeansOfType(EntityManager.class);
Try calling
EntitiyManagerFactory factory =
(EntityManagerFactory) ctx.getBean("myEntityManagerFactoryBean")
EntityManager em = factory.createEntityManager();
where "myEntityManagerFactorBean" is your LocalContainerEntityManagerFactoryBean
But why would you need that?
I use the SpringJUnit4ClassRunner
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:jndiContext-mock.xml",
"classpath:spring/testContext.xml" })
The clase under test is injected via the mock context. With this annotated it will get the entity manager via injection.
#PersistenceContext
protected HibernateEntityManager entityManager;

Resources