What's the best way to get EJB3, EJBLocal Object in MDB Class ?
Thanks.
The best way is injection
#MessageDriven
public class MsgBean implements MessageListener {
#EJB
private ServiceBean service;
public void onMessage(Message msg) {
service.process(msg);
}
}
Related
I need to audit invocations of ejb beans. Saying audit I mean write informations such as current logged user, method name, additional description to a database. I decided to do it by use of CDI decorator:
#Decorator
public class AccountServiceBeanDecorator implements AccountService {
#Inject
#Delegate
#Any
AccountService accountService;
#EJB
private AuditService auditService;
#Override
public Account createAccount(Account account) {
auditService.saveAudit("Method: createAccount", currentUser, "Creating account by admin");
return accountService.createAccount(account);
}
}
and the decorated class:
#Stateless
public class AccountServiceBean implements AccountService {
#Override
public Account createAccount(Account account) {
...
}
}
Now if I call AccountService from another ejb stateless bean, what will happen with transaction?:
#Stateless
public ApplicationFacadeBean implements ApplicationFacade {
#EJB
private AccountService accountService;
#Override
public Account createAccount(Account account) {
return accountService.createAccount(account);
}
}
I wanted to log transaction status in decorator (AccountServiceBeanDecorator) and decorated class (AccountServiceBean), so I injected TransactionSynchronizationRegistry as a resource in both classes:
#Decorator
public class AccountServiceBeanDecorator implements AccountService {
#Inject
#Delegate
#Any
AccountService accountService;
#EJB
private AuditService auditService;
#Resource
private TransactionSynchronizationRegistry reg;
#Override
public Account createAccount(Account account) {
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
log.info("tx ({}): {}", new Object[] {reg.getTransactionStatus(), reg.getTransactionKey()});
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
auditService.saveAudit("Method: createAccount", currentUser, "Creating account by admin");
return accountService.createAccount(account);
}
}
and
#Stateless
public class AccountServiceBean implements AccountService {
#Resource
private TransactionSynchronizationRegistry reg;
#Override
public Account createAccount(Account account) {
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
log.info("tx ({}): {}", new Object[] {reg.getTransactionStatus(), reg.getTransactionKey()});
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
...
}
}
I received strange behavior:
log from decorator
tx (0): JavaEETransactionImpl: txId=6 nonXAResource=null jtsTx=null localTxStatus=0 syncs=[com.sun.ejb.containers.ContainerSynchronization#68fb15d0]]]
NullPointerException on second log (reg is null).
Can anybody explain it to me? Wheter AccountServiceBean class is called within the same transaction as ApplicationFacade?
Thank you
first: i would not mixing ejbs with cdi interceptors. ejbs has it on interceptor implementations.
second: interceptors are executed in the same transaction as the ejb where the interceptor is around.
possible solution:
create a correct ejb interceptor
put the interceptor around the method / class
create a second ejb (MyLoggerBean) with a method like this logToDatabase(String message) and annotate this method with #TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
inside the interceptor create a class member like this: #EJB private MyLoggerBean loggerBean
inside your #AroundInvoke annotated method you could call loggerBean. logToDatabase(...)
this would create a new transaction from inside the current transaction of the ejb where the interceptor is around
--> i know my english is not very good. but i hope that you understand what i think should work. if i have the time, i make e example on github...
Hmm... what container are you using? Generally I wouldn't suspect a CDI decorator to work on an EJB... I can't think of anything in the JEE spec that I've encountered that would give evidence either way.
Faced with your problem though, I did this with an interceptor, not a decorator. These are supported by the EJB spec... Anyway, here's my code, you would need to grab the variables from the context in your case:
import java.lang.reflect.Method;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
public class InvocationCountInterceptor {
#Inject
private InvocationCounter counter;
#AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
Object returnValue = ctx.proceed();
Class<? extends Object> className = ctx.getTarget().getClass();
Method methodName = ctx.getMethod();
counter.incrementCounter(className, methodName);
return returnValue;
}
}
Then whatever EJB or EJB Method you want to audit, I just added this: #Interceptors(InvocationCountInterceptor.class)
So I have an Interface as follows
public interface IMembershipProvider
{
bool GetUserGuidFromSSOToken(string ssoToken, out string userGuid, out int statusCode);
}
And a Class as Follows which Implements the above Interface
public class MembershipProvider : IMembershipProvider
{
public bool GetUserGuidFromSSOToken(string ssoToken, out string userGuid, out int statusCode)
{
....Method Contents
}
}
And then in my Presenter I have the following
private IMembershipProvider Provider;
..
if (!Provider.GetUserGuidFromSSOToken(ObSSOCookie.Value, out userGuid, out statusCode))
And when this is called it use the code for the method from MembershipProvider class, but I am just wondering how that's possible when the MembershipProvider is never referenced in the Presenter ?
The MembershipProvider instance must be injected into the Presenter using dependency injection.
Some kind of service factory provider is usually what I do.
private IMembershipProvider Provider =
MembershipProviderService.GetDefaultProvider();
...
internal class MembershipProviderService
{
IMembershipProvider GetDefaultProvider()
{
return new MembershipProvider();
}
}
I've a CDI Sterotypes which contains some of InterceptorBinding as the following: -
#Inherited
#InterceptorBinding
#Retention(RetentionPolicy.RUNTIME)
#Target({
ElementType.METHOD,
ElementType.TYPE})
#Documented
public #interface MyInterceptable {
}
#Interceptor
#MyInterceptable
public class MyInterceptor {
#AroundInvoke
public Object perform(InvocationContext context) throws Exception {
log.info("My Interceptor begin.");
Object result =context.proceed();
log.info("My Interceptor end.");
return result;
}
}
#Stereotype
#MyInterceptable
#Retention(RetentionPolicy.RUNTIME)
#Target({
ElementType.TYPE
})
#Documented
public #interface MyStereoable {
}
When I define this Sterotype at the non-EJB it is worked correctly. The message is printed before and after the doing1() execution.
#Singleton
#MyStereoable
public class MyCustomized {
public void doning1(){
//print something.
}
}
Anyhow, when I've tried to use this with the Stateless EJB, it is not worked. There is no any message printed by the Interceptor.
#Remote
public interface HelloServiceable extends Serializable {
void doning2();
}
#Stateless
#MyStereoable
public class HelloService implements HelloServiceable {
public void doing2() {
//Print something
}
}
Then I mix the case 1 and case2 as the following: -
#Stateless
#MyStereoable
public class HelloService implements HelloServiceable {
#Inject
private MyCustomized myBean;
public void doing2() {
this.myBean.doing1();
//Print something
}
}
The MyCustomized can be intercepted and the message is printed, but not for the Stateless EJB.
I'm not sure if I am misunderstand or confused about the CDI and EJB or not. Could you please help to advise further? Thank you very much for your help in advance. I'm looking forward to hearing from you soon.
Regards,
Charlee Ch.
I've changed my project from EAR/EJB project to standalone Web project. The CDI Stereotype is now worked with EJB Session Bean.
I've created a small demonstration at github. Please take note, It uses the JBoss Arquillian for testing.
I hope this information maybe useful.
Regards,
Charlee Ch.
I am using unity, entity framework 4 with POCO classes, repository pattern for DAL and services for Business Logic control.
I also want to use Unit of Work so I can package together CRUD operations which I perform on different services and then commit them all together.
My question is what would be the proper way to inject the Unit Of Work mechanism into my application using Microsoft Unity?
I understand that I can put the IUnitOfWork together with the repository on the constructor of the proper service and then if Unity mapping is specified it would auto initiate the proper instances, but this way I do not pass the global unit of work but rather create a new instance on each level, which can't be a smart way to do it (actually the repository is initiated even before the service).
What am I missing? (Attached is constructor code as I wrote it now of service and its repository).
U also understand that I can use Unity's ParameterOverrides method to take some global instance of Unit of Work (lets say from my aspx.cs file) and pass it into the service and then into the repository. But it seems a bit lame. Is this my only option?
Thanks
public class GenericRepository<T> : IUnitOfWorkRepository, IGenericRepository<T> where T : BaseEntity, IAggregateRoot
{
private IUnitOfWork _uow;
/// <summary>
/// Returns the active object context
/// </summary>
private ObjectContext ObjectContext
{
get
{
return ObjectContextManager.GetObjectContext();
}
}
public GenericRepository(IUnitOfWork uow)
{
_uow = uow;
}
//blahhhh...
public void Add(T entity)
{
_uow.RegisterNew(entity, this);
}
public void Delete(T entity)
{
_uow.RegisterRemoved(entity, this);
}
//.....blah blah....
public void PersistCreationOf(IAggregateRoot entity)
{
this.ObjectContext.AddObject(GetEntitySetName(), entity);
}
public void PersistUpdateOf(IAggregateRoot entity)
{
// Do nothing as EF tracks changes
}
public void PersistDeletionOf(IAggregateRoot entity)
{
this.ObjectContext.DeleteObject(entity);
}
}
public class CategoryRepository : GenericRepository<XComSolutions.FB.Domain.Model.Entities.Category>, ICategoryRepository
{
public CategoryRepository(IUnitOfWork uow)
: base(uow)
{ }
}
public class CategoryService : ICategoryService
{
public int myID {get; set;}
private ICategoryRepository _categoryRepository;
private IUnitOfWork _uow;
public CategoryService(ICategoryRepository categoryRepository,
IUnitOfWork uow)
{
_categoryRepository = categoryRepository;
_uow = uow;
}
public List<Category> GetAll()
{
return _categoryRepository.GetAll();
}
}
Define an IUnitOfWorkFactory and inject that in your services:
public class Service
{
private readonly IUnitOfWorkFactory factory;
public Service(IUnitOfWorkFactory factory)
{
this.factory = factory;
}
public void DoOperation()
{
using (UnitOfWork context = this.factory.CreateNew())
{
this.DoSomeStuff(context);
this.DoMoreStuff(context);
context.SubmitChanges();
}
}
}
What I think you need to do is to define unit of work factory. You register this factory with your DI container and you resolve for this factory every time you need your unit of work. Then you get unit of work from the factory, work with it and let it go. You often will see that you need your unit of work within a scope of single method or single class. This article discuss Unit of Work pattern in connection with Entity Framework: http://msdn.microsoft.com/en-us/magazine/dd882510.aspx
Im trying to implement an unit of work pattern by passing an unit of work instance into my repositories.
Relevant code from Global.asax.
public class SiteModule : NinjectModule
{
public override void Load() {
Bind<IUnitOfWork>().To<SqlUnitOfWork>()
.InRequestScope()
.WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["Entities"].ConnectionString);
Bind<IProductRepository>().To<ProductRepository>();
Bind<ICategoryRepository>().To<CategoryRepository>();
}
}
Repository constructors:
public class ProductRepository {
IUnitOfWork unitOfWork;
public ProductRepository(IUnitOfWork unitOfWork) {
this.unitOfWork = unitOfWork;
}
}
public class CategoryRepository {
IUnitOfWork unitOfWork;
public CategoryRepository(IUnitOfWork unitOfWork) {
this.unitOfWork = unitOfWork;
}
}
What i want is that a maximum of 1 instance of SqlUnitOfWork is created per request and is passed into my repositories (via their respective constructors).
Is the InRequestScope() method on the IUnitOfWork binding enough? If not how can i achieve this?
The code you have will work fine. Only one instance of IUnitOfWork will be given to any class that requests it (via constructor/property injection or calls to the kernel's .Get<> etc.)