How can a persistenceContext link with multiple EntityManager - entity

Recently I have gone through PRO JPA2 book and find that "A single persistence context can be link with multiple EntityManager instance."
I have searched for the same but could not found satisfactory answer. Can anybody elaborate this with example?

It's difficult to know exactly what was meant without more context from the book. That said, if you're using container-managed JPA within a global transaction, then each injected EntityManager referring to the same persistence unit will be backed by the same persistence context. For example:
#Stateless
public class Bean {
#PersistenceContext
EntityManager em1;
#EJB
OtherBean otherBean;
#TransactionAttribute(REQUIRED) // The type, but for illustration
public void doWork() {
// ... use em1
otherBean.doMoreWork();
}
}
#Stateless
public class OtherBean {
#PersistenceContext
EntityManager em2;
public void doMoreWork() {
// ... use em2, it shares a persistence context with em1
}
}

Related

Resteasy and Google Guice: how to use multiple #ApplicationPath and resource with #Injection?

I created a project to test the dependency injection offered by Google Guice in my Jax-rs resources, using Resteasy.
My intentions are:
Use multiple #ApplicationPath for the versions of my API. In each class annotated with #ApplicationPath I load a set of classes for the specific version.
Each resource have a #Inject (from Google Guice) in his constructor to inject some services.
I created two classes annotated with #ApplicationPath: ApplicationV1RS and ApplicationV2RS. In both I added the same resources classes (UserResource and HelloResource), only for my test.
My Module is configured like this:
public class HelloModule implements Module
{
public void configure(final Binder binder)
{
binder.bind(IGreeterService.class).to(GreeterService.class);
binder.bind(IUserService.class).to(UserService.class);
}
}
When I call http://localhost:9095/v1/hello/world or http://localhost:9095/v2/hello/world, I receive the same error:
java.lang.RuntimeException: RESTEASY003190: Could not find constructor
for class: org.jboss.resteasy.examples.guice.hello.HelloResource
Well, as I expected, this not works. The Google Guice is not "smart" to instantiate the resource classes using the construtor for me.
But I can't find a way to work. To be really honest, I'm really confuse about how the Google Guice, Jetty and Resteasy play with each other in this scenario.
If I abandon the idea of use #ApplicationPath, my resources work with Google Guice configuring my HelloModule like this:
public class HelloModule implements Module
{
public void configure(final Binder binder)
{
binder.bind(HelloResource.class);
binder.bind(IGreeterService.class).to(GreeterService.class);
binder.bind(UserResource.class);
binder.bind(IUserService.class).to(UserService.class);
}
}
But in this case, I'm passing the control to register my resources (HelloResource and UserResource) to Guice. It's not flexible for me, I can't setup my multiple #ApplicationPath.
So, what I'm missing or not understanding?
I created a project with the problemetic code. Is very easy to setup and test: https://github.com/dherik/resteasy-guice-hello/tree/so-question/README.md
Thanks!
When you have getClasses method in your Application then it tries to create instance for all the registered resources using the default constructor which is missing in our Resources class. One way is to create a default constructor and Inject the dependencies through setter Injection.
And then instead of overriding getClasses in ApplicationV1RS and ApplicationV2RS you override getSingletons. Since Resources can be Singleton.
Below are the changes that I made to make it work the way you want.
ApplicationV1RS.java
#ApplicationPath("v1")
public class ApplicationV1RS extends Application {
private Set<Object> singletons = new HashSet<Object>();
public ApplicationV1RS(#Context ServletContext servletContext) {
}
#Override
public Set<Object> getSingletons() {
Injector injector = Guice.createInjector(new HelloModule());
HelloResource helloResource = injector.getInstance(HelloResource.class);
UserResource userResource = injector.getInstance(UserResource.class);
singletons.add(helloResource);
singletons.add(userResource);
return singletons;
}
}
ApplicationV2RS.java
#ApplicationPath("v2")
public class ApplicationV2RS extends Application {
private Set<Object> singletons = new HashSet<Object>();
public ApplicationV2RS(#Context ServletContext servletContext) {
}
#Override
public Set<Object> getSingletons() {
Injector injector = Guice.createInjector(new HelloModule());
HelloResource helloResource = injector.getInstance(HelloResource.class);
UserResource userResource = injector.getInstance(UserResource.class);
singletons.add(helloResource);
singletons.add(userResource);
return singletons;
}
}
HelloResource.java
#Path("hello")
public class HelloResource {
#Inject
private IGreeterService greeter;
public HelloResource() {
}
#GET
#Path("{name}")
public String hello(#PathParam("name") final String name) {
return greeter.greet(name);
}
}
UserResource.java
#Path("user")
public class UserResource {
#Inject
private IUserService userService;
public UserResource() {
}
#GET
#Path("{name}")
public String hello(#PathParam("name") final String name) {
return userService.getUser(name);
}
}
Add #Singleton to your Service Classes.
Hope it helps.
I have also pushed the code to forked repo. check it out

Google guice inject a instance created by Spring and method intercept

I use Gucie 3.0 to intercept any methods that have my defined annotation #LogRequired. However for my application, some beans are initialized by Spring with injected fields values. After calling giuce injector.injectMembers(this), the beans gets proxied by guice but all original fields values are gone. Looks like Guice re-constucts the beans and throw away all old values. Is this expected behavior or how can I solve this issue?
Create a class extends AbstractModule
public class InterceptorModule extends AbstractModule{ public void configure()
{ LogInterceptor tracing = new LogInterceptor(); requestInjection(tracing); bindInterceptor(Matchers.any(), Matchers.annotatedWith(LogRequired.class), tracing); }
}
Define the interceptor business logic
public class LogInterceptor implements MethodInterceptor { //business logic here }
Create LogService class
Public class LogService { Injector injector = Guice.createInjector(new InterceptorModule()); }
I have one of the bean example below with the getName method wants to be intercepted:
public class UserImplTwo implements IUser {
private String name;
#LogRequired
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
which is initialized by Spring context:
Finally I have a consumer to consume the bean:
public class Consumer
{
#Inject
private UserImplTwo instance;
public void setInstance(UserImplTwo instance)
{
this.instance = instance;
}
public void init()
{
// the value of name is printed out as 'hello world'
System.out.println( this.instance.getName());
LogService.injector.injectMembers(this);
// the value of name is printed out as null, should be 'hello world'
System.out.println( this.instance.getName());
}
}
Then use Spring to initialized the bean:
<bean id="consumer" class="com.demo.Consumer" init-method="init">
<property name="instance" ref="userTwo"></property>
</bean>
Please let me know if this the the right approach or if I did something wrong, because I have to use Spring to initialize some beans.
A "right approach" is probably to keep things simple and use Spring's DI if you use Spring Framework, and not try to mix and match with Guice :-)
Having said that there seems no technical reason why they can't be mixed and matched together to some degree.
I think you will have more success with another approach. One that I have used before is to make use of Spring MVC Java-based configuration. Here is the basic approach.
Create a class that extends WebMvcConfigurationSupport:
#Configuration
#Import(BeansConfig.class)
public class Config extends WebMvcConfigurationSupport {
}
Separate out your beans config (probably it can be merged with the above but I guess it's quite dull code and you normally don't want want to see it). And use it to create your beans with your Guice injector before providing them to Spring.
#Configuration
public class BeansConfig {
#Bean
public Consumer getConsumer() {
return SomeGuiceInjectorFactory.newInstance(Consumer.class);
}
}
Include this in your spring.xml (or bootstrap other ways if your servlet container is newer than mine was)
<context:annotation-config/>
<bean id="extendedWebMvcConfig" class="Config"/>
Constructor injection and most/all? other Guice goodness should work also with such scenario.
Also you won't need to configure your beans in xml.

EJB 3.1 : Singleton bean not getting injected inside another stateless bean though both beans are getting registered

Here is my bean that is trying to inject a singleton bean InformationService :
#Path("/information/{name}")
#Stateless (name="InformationResource")
public class InformationResource {
#EJB
private InformationService appService;
#GET
#Produces(MediaType.APPLICATION_XML)
public Information getInfo(#PathParam("name") String name){
return appService.getMap().get(name);
}
#PUT
#POST
#Consumes(MediaType.APPLICATION_XML)
public Information putInfo(#PathParam("name") String name, Information info){
return appService.getMap().put(name,info);
}
#DELETE
public void deleteInfo(#PathParam("name") String name){
appService.getMap().remove(name);
}
}
This is the InformationService class
#Singleton
public class InformationService {
private Map<String,Information> map;
#PostConstruct
public void init(){
map = new HashMap<String,Information>();
map.put("daud", new Information("B.Tech","Lucknow"));
map.put("anuragh", new Information("M.Sc","Delhi"));
}
public Map<String,Information> getMap(){
return map;
}
}
Its part of a very simple JAX-RS implementation and I am deploying as war in JBoss 6.1 Final. The problem is that InformationService throwing a NullPointerException when I make the proper get request. If I initialize appService explicitly, everything works fine. Why is #EJB annotation not working ?
Are you using Jersey as REST implementation? If so, EJB injection is not supported out of the box.
This link provides more information on this and also a solution.
Check that your #Singleton is javax.ejb.Singleton.
Any other exceptions before NPE ?

Entity framework DbContext in wcf per call instance mode

I have a repository like this
public abstract class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected DbContext _dbContext;
public BaseRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public TEntity GetByKey(object keyValue)
{
// todo
}
}
and a concrete repository like this
public CustomerRepository : BaseRepository<Customer> , ICustomerRepository
{
public CustomerRepository(DbContext context) : base (context) { }
public Customer FindCustomerByKey(string key)
{
_dbContext.Set<Customer>().Find(key);
}
}
I have wcf service like this
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class CustomerSatisfactionService : ICustomerSatisfactionService
{
private ICustomerRepository _customerRepository;
private IHelpDeskRepository _helpdeskRepository;
public AccountService(ICustomerRepository customerRepository,IHelpdeskRepository helpdeskRepository)
{
_customerRepository = customerRepository;
_helpdeskRepository = helpdeskRepository;
}
public void DoSomethingUsingBothRepositories()
{
// start unit of work
// _customerRepository.DoSomething();
// _helpdeskRepository.DoSomething();
// commit unit of work
}
}
and I am using StructureMap for injecting DbContext instances like this
For<DbContext>().Use(() => new MyApplicationContext());
My problem is when a client calls the service, a new CustomerSatisfactionService instance is created, hence new instances of CustomerRepository and HelpdeskRepository are created but with different DbContexts.
I want to implement the unit of work pattern, but in the DoSomethingWithBothRepositories method, the two repositories have different DbContexts.
Is there any way to tell structure map to spin up a DbContext instance on a per call basis?
You must specify lifecycle for your DbContext so that only one instance is created per call. StructureMap doesn't contain build-in lifecycle management for per call WCF but you can find one implementation on this blog.
You need to implement UnitOfWork pattern so that same context is shared amongst entities. Take a look at http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx for a way to implement it.
I don't know if you need/want StructureMap to control the instantiation of dbcontext, have a look at this reply, UoW and UoW Factory setup dbcontext for the calls that need to be made in the repository.
EF ObjectContext, Service and Repository - Managing context lifetime.

NHibernate - Is it OK to use an abstract base to provide functionality instead of an interface?

I'm fairly new to NHibernate and have run into a strange inheritance chaining issue with my repository classes. I've been using Gabriel Schenker's FAQ as a reference, and following his examples I've been creating interfaces to define contracts for DAO operations in "repository" classes. The data schema I'm working with is rather extensive, and after a little while I found myself duplicating a lot of code. Specifically, the Add, Update, Delete, and "GetByID" methods were exactly the same after I added a generic "EntityType" parameter to the base interface. So, for example, this would be the most basic interface for repository operations:
public interface IBasicRepository<EntityType> where EntityType : class
{
void Add(EntityType entity);
void Remove(EntityType entity);
void Update(EntityType entity);
EntityType GetByID<IDType>(IDType id);
}
I'll just talk about the Add method from now on, for the sake of brevity. With the generic EntityType, the implementations were all the same:
public void Add(EntityType entity)
{
using (ISession session = NHUtility.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(entity);
transaction.Commit();
}
}
}
Obviously, typing this same method body repeatedly (with the slight change of type) isn't only annoying, it's bad design in my book. So I created an abstract base class I'll call RepositoryBase which provides the implementation for Add(). Since I'm using an abstract instead of an interface, I "break the interface chain" for classes inheriting from RepositoryBase and am forced to make any derivation abstract as well, even though it seems more "correct" to use an interface. Using this crappy little entity example....
public class Entity1
{
public Guid ID { get; set; }
public String Name { get; set; }
}
...one can't do this...
public interface IEntity1Repository : RepositoryBase<Entity1>
{
//Illegal!!!! Bad, naughty programmer!
}
...but this is fine....
public abstract class Entity1RepositoryBase : RepositoryBase<Entity1>
{
public abstract ICollection<Entity1> GetByName(string name);
}
This just bothers me. It works, but it rubs me the wrong way, especially as the chain of inheritance/implementation with this particular schema could go quite deep. So I guess my questions are:
Am I just being stupid and anal retentive about this?
Is there a different/better design that I should be looking at here? I've looked at some other examples (notably Billy McCafferty's) and Schenker's approach seems simplest for novice NHibernating.
Thanks in advance.
One option could be:
public interface IRepository<T> where T: class
{
void Add(T entity);
void Remove(T entity);
void Update(T entity);
T GetByID<IDType>(IDType id);
}
With a base class that implements that interface. Ie:
public abstract class RepositoryBase<T> : IRepository<T> where T: class
{
...
}
Which is then extended for each type of entity if necessary:
public interface IProductRepository : IRepository<Product>
{
// Add extra methods
}
public class ProductRepository : RepositoryBase<Product>, IProductRepository
{
// Implement extra methods
}