Accessing DB via JPA in Wicket IResource? - spring

I want to implement an DynamicImageResource which will be mounted in a Wicket 6.7/Spring 3.2/JPA 2 application. This DynamicImageResource shall retrieve information based on input parameters and create a response.
The question is: How can i access the DB from within DynamicImageResource.getImageData(...)? I can't inject a #PersistenceContextenter code here or a DAO via #SpringBean. My last resort would be a static PersistenceContextFactory.
Any better ideas? Or best practices?

As Wicket manages component instanciation for you, or you manually instanciate objects via their respective constructors, injection mechanisms couldn't work out of the box (the object are, per manual constructor invocation, unmanaged by your container).
Wicket provides built-in injection for Component via inheritance, the magic behind is Wicket calling componentInstanciationListeners. For every unmanaged class not inherited from an injection enabled one, you have to manually trigger the injection on your bean.
As stated in the comment, you should call Injector.get().inject(this); in your constructor in order for it to work.

To complete the whole thing, i'll past my PersistenceContextBridge Spring bean here. It wraps an EntityManager, which will be injected via #PersistenceContext. By using the Lombok annotation #Delegate all calls to the bean will be delegated to the EntityManager.
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import lombok.Delegate;
import org.springframework.stereotype.Service;
#Service
public class EntityManagerBridge implements EntityManager {
#Delegate
#PersistenceContext
private EntityManager em;
}
Now all i have to do in my Wicket component is to inject EntityManagerBridge as #SpringBean:
#SpringBean
private EntityManager em; // inject EntityManagerBridge (implements EntityManager)
public MyFancyResource() {
Injector.get().inject(this); // enable Spring injection for
}

Related

Can I inject an JPA EntityManager using CDI and #PersistenceContext, like with Spring?

In Spring, I can inject an javax.persistence.EntityManager
into a Spring bean using the annotation #javax.persistence.PersistenceContext, like this:
#Service
public class MyRepository {
#PersistenceContext
private EntityManager entityManager;
}
This is documented in the Spring docs in chapter 20.5.2 Implementing DAOs based on plain JPA.
Is there a way to do this using CDI (specifically, Weld) if I am not using a Java EE container?
In particular, is it possible to reuse the annotation #PersistenceContext for CDI (because existing code uses it with Spring) ?
As far as I understand: When using a Java EE container, the container will interpret the annotation and inject an EntityManager. Is that correct? And is there a way to get this to work using Weld, but without a Java EE container?
I tried to inject the class above into another class using Weld (in Tomcat, without Java EE). The injection takes place, so Weld correctly creates an instance of MyRepository, however the field MyRepository.entityManager is null, as if the annotation #PersistenceContext was ignored.
What is happening (or rather, not happening) here?
You can do it this way:
create Entity Manager Factory Producer
public class EntityManagerFactoryProducer {
#Produces
#ApplicationScoped
public EntityManagerFactory create() {
return Persistence.createEntityManagerFactory("PU");
}
public void destroy(#Disposes EntityManagerFactory factory) {
factory.close();
}
}
and create Entity Manager Producer
public class EntityManagerProducer {
#Inject
transient EntityManagerFactory emf;
#Produces
#RequestScoped
public EntityManager create() {
return emf.createEntityManager();
}
public void destroy(#Disposes EntityManager em) {
em.close();
}
}
then you can use dependency injection (CDI will create one em for each request)
#Inject
EntityManager entityManager;
You have to start the CDI context in your main method
public static void main(String[] args) throws IOException {
Weld weld = new Weld();
WeldContainer container = weld.initialize();
Application application = container.instance().select(Application.class).get();
application.run();
weld.shutdown();
}
ps. If you have more then one PU use #Qualifier
While MilkMaid's answer is a sound way to go, I would just add a few more behind-the-scenes hints.
Is there a way to do this using CDI (specifically, Weld) if I am not using a Java EE container?
Short answer - there is. Weld can allow for injection of next to any object you wish to have injectable, however you need to mind who owns/manages this object. In your case, it is EntityManager which is stuff from JPA, so guess what - JPA manages the lifecycle of such object. Therefore you need to create a "wrapper" (in reality its a proxy) for such object which will be handled by CDI/Weld. And that what you need producer for.
as if the annotation #PersistenceContext was ignored.
Indeed, it is ignored. Here is a simplification of what happens. Normally, that is in EE container, Weld would make the injection happen but the real magic behind that is not a Weld core code, but rather an integration on the EE server side (who adopts Weld SPI to handle such annotations and turn them into beans which it then injects).
Generally speaking, trying to handle 'EE stuff' outside of EE containers might get tricky as you come across a lot of integration which originally happens inside the container, but you now need to handle that yourself.
Technically one could probably make the #PersistenceContext annotation work, maybe by writing a CDI extension. However, that is a nasty hack rather than anything else - one would be bending the EE-only annotation for SE usage. I would advise against it, but if you still want to go that way, the idea would be to basically make CDI think the #PersistanceContext is yet another #Inject plus provide the producer. This would mean a LOT of manual work, there is no in-built mechanism in CDI to handle that for you - this is normally the EE server's responsibility.

why jsf save state of bean in different browsers [duplicate]

I have a #RequestScoped bean with a List property.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.springframework.stereotype.Controller;
#Controller
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
private List list;
// getters and setters
}
This property is linked to a datatable:
<ice:dataTable value="#{myBean.list}" ..other stuff.. />
The List is dynamically filled with no problem, and the datatable is displayed with no problems. But if, I navigate to another page, and then go back to the initial page the datatable is still with the data of the initial request. It shouldn't be empty again? If the bean is request scoped it should be destroyed after the request, and I should get and empty datatable as the beginning.
Even more strange is that if I open the page in one browser (like Firefox), fill the datatable with a request, then I open another browser (like Chrome) and go to the datatable page, it is filled with the data from previous request from another browser! I think the bean is behaving like an application one.
Any ideas?
Update 1: The class is not static neither its variables. Also, I disable tomcat cache, but still not working.
Update 2: I think probably found the problem. My backing beans are annotated with #Controller from Spring. I use this annotation because then use #Autowired to bind services. Could be this is creating a singleton and that why is not being created and destroyed with every request? I think pretty sure the problem is in the mix of Spring and JSF2 annotations.
You shouldn't manage a single bean by multiple different bean management frameworks like JSF, CDI and Spring. Choose the one or the other. When managing the bean by for example Spring's #Controller, all bean management related annotations of other frameworks like JSF's #ManagedBean and CDI's #Named are ignored.
I don't do Spring and I have no idea why you're using it instead of the standard Java EE 6 API, but the symptoms and documentation indicates that the scope of such a Spring bean indeed defaults to the application scope. You need to specify the bean scope by Spring #Scope annotation. You would also like to remove the JSF bean management annotations since they have no value anymore anyway and would only confuse the developer/maintainer.
#Controller
#Scope("request")
public class MyBean implements Serializable {
// ...
}
Alternatively, you can also get rid of Spring #Controller annotation and stick to JSF #ManagedBean. You can use #ManagedProperty instead of #Autowired to inject another #ManagedBean instance or even a Spring managed bean (if you have Spring Faces EL resolver configured), or the Java EE standard #EJB to inject an #Stateless or #Stateful instance.
E.g.
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
#EJB
private SomeService service;
// ...
}
See also:
Spring JSF integration: how to inject a Spring component/service in JSF managed bean?

#Autowired vs #PersistenceContext for EntityManager bean

What is the difference between:
#Autowired
private EntityManager em;
versus:
#PersistenceContext
private EntityManager em;
Both options work in my application, but can I break something by using the #Autowired annotation?
You shouldn't use #Autowired.
#PersistenceContext takes care to create a unique EntityManager for every thread. In a production application you can have multiple clients calling your application in the same time. For each call, the application creates a thread. Each thread should use its own EntityManager. Imagine what would happen if they share the same EntityManager: different users would access the same entities.
usually the EntityManager or Session are bound to the thread (implemented as a ThreadLocal variable).
Source: https://stackoverflow.com/a/42074452/2623162
EntityManager instances are not thread-safe.
Source: https://docs.oracle.com/cd/E19798-01/821-1841/bnbqy/index.html
Please notice that #PersistenceContext annotation comes from javax.persistence package, not from spring framework. In JavaEE it is used by the JavaEE container (aka the application server) to inject the EntityManager. Spring borrowed the PersistenceContext annotation to do the same: to inject an application-managed (= not container-managed) EntityManager bean per thread, exactly as the JavaEE container does.
#PersistenceContext allows you to specify which persistence unit you want to use. Your project might have multiple data sources connected to different DBs and #PersistenceContext allows you to say which one you want to operate on
check the explanation here:
http://www.coderanch.com/t/481448/java-EJB-SCBCD/certification/unitName-PersistenceContext
#PersistenceContext:
does not return entity manager instance
it returns container-managed proxy that acquires and releases presistence context on behalf of the application code
#PersistenceContext is a JPA standard annotation designed for that specific purpose. Whereas #Autowired is used for any dependency injection in Spring. Using #PersistenceContext gives you greater control over your context as it provides you with ability to specify optional elements e.g. name, properties
I think #Autowire will work same way as #PersistenceContext
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.misc.jpa-context
When working with multiple EntityManager instances and custom
repository implementations, you need to wire the correct EntityManager
into the repository implementation class. You can do so by explicitly
naming the EntityManager in the #PersistenceContext annotation or, if
the EntityManager is #Autowired, by using #Qualifier.
As of Spring Data JPA 1.9, Spring Data JPA includes a class called
JpaContext that lets you obtain the EntityManager by managed domain
class, assuming it is managed by only one of the EntityManager
instances in the application. The following example shows how to use
JpaContext in a custom repository:
You can create the following FactoryBean to make EntityManager properly injectable, even via constructor injection:
/**
* Makes the {#link EntityManager} injectable via <i>#Autowired</i>,
* so it can be injected with constructor injection too.
* (<i>#PersistenceContext</i> cannot be used for constructor injection.)
*/
public static class EntityManagerInjectionFactory extends AbstractFactoryBean<EntityManager> {
#PersistenceContext
private EntityManager entityManager;
#Override
public Class<?> getObjectType() {
return EntityManager.class;
}
#Override
protected EntityManager createInstance() {
return entityManager;
}
}
Please note, that because we use the #PersistenceContext annotation internally, the returned EntityManager will be a proper thread-safe proxy, as it would have been injected directly at the place of usage with field injection (using #PersistenceContext).

Relation betweenn hibernate and spring

I have a question about spring + hibernate
I always use hibernate for my develeppoment, I generate images of the tables and the class DAO
then at logic metier I make simple calls to these methods dao ....
for exemple UserDao=new UserDao () then userdao.persist() ...
Now I have intgret spring, and I do not yet understand ..
1
what is the plus made ​​by him knowing that he is also making calls
has dao Service (the writings that manually) it does not generate the
class dao with hibernate
2
is that with spring I would not worry about manage session for
example open session, close session commit() ...
thank you in advance I would like to have an idea Ccool:
At its core, Spring is a dependency injection framework. This means that instead of doing
public class MyService
private MyDao dao;
public MyService() {
dao = new MyDao();
}
}
You can do
public class MyService
private MyDao dao;
#Autowired
public MyService(MyDao dao) {
this.dao = dao;
}
}
And Spring will automatically call the constructor and inject an instance of MyDao. The main benefit is that the code is easily unit-testable.
On top of that, it allows injecting proxies instead of the actual implementations directly. These proxies will indeed handle the transaction management for you, and more (exception translation, security checks, etc.).
So instead of explicitely opening, committing and rollbacking transactions, you would simply annotate a service method with #Transactional, and Spring would open, commit/rollback the transaction. And the transaction context would automatically propagate to the nested service calls.
This short answer is only to give you an idea. To learn more, read about dependency injection, and read the Spring documentation.
Use Spring annotations like #Service for service classes, #Repository for Dao classes and #Controller for action controllers. Use of #Transactional on service class or methods is suffice to carry out transactions.

Data from #RequestScoped bean is shared in different browsers

I have a #RequestScoped bean with a List property.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.springframework.stereotype.Controller;
#Controller
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
private List list;
// getters and setters
}
This property is linked to a datatable:
<ice:dataTable value="#{myBean.list}" ..other stuff.. />
The List is dynamically filled with no problem, and the datatable is displayed with no problems. But if, I navigate to another page, and then go back to the initial page the datatable is still with the data of the initial request. It shouldn't be empty again? If the bean is request scoped it should be destroyed after the request, and I should get and empty datatable as the beginning.
Even more strange is that if I open the page in one browser (like Firefox), fill the datatable with a request, then I open another browser (like Chrome) and go to the datatable page, it is filled with the data from previous request from another browser! I think the bean is behaving like an application one.
Any ideas?
Update 1: The class is not static neither its variables. Also, I disable tomcat cache, but still not working.
Update 2: I think probably found the problem. My backing beans are annotated with #Controller from Spring. I use this annotation because then use #Autowired to bind services. Could be this is creating a singleton and that why is not being created and destroyed with every request? I think pretty sure the problem is in the mix of Spring and JSF2 annotations.
You shouldn't manage a single bean by multiple different bean management frameworks like JSF, CDI and Spring. Choose the one or the other. When managing the bean by for example Spring's #Controller, all bean management related annotations of other frameworks like JSF's #ManagedBean and CDI's #Named are ignored.
I don't do Spring and I have no idea why you're using it instead of the standard Java EE 6 API, but the symptoms and documentation indicates that the scope of such a Spring bean indeed defaults to the application scope. You need to specify the bean scope by Spring #Scope annotation. You would also like to remove the JSF bean management annotations since they have no value anymore anyway and would only confuse the developer/maintainer.
#Controller
#Scope("request")
public class MyBean implements Serializable {
// ...
}
Alternatively, you can also get rid of Spring #Controller annotation and stick to JSF #ManagedBean. You can use #ManagedProperty instead of #Autowired to inject another #ManagedBean instance or even a Spring managed bean (if you have Spring Faces EL resolver configured), or the Java EE standard #EJB to inject an #Stateless or #Stateful instance.
E.g.
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
#EJB
private SomeService service;
// ...
}
See also:
Spring JSF integration: how to inject a Spring component/service in JSF managed bean?

Resources